How to find files by file type?











up vote
8
down vote

favorite
1












I know I can find files using find: find . -type f -name 'sunrise'. Example result:



./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise


I also know that I can determine the file type of a file: file sunrise. Example result:



sunrise: PEM RSA private key


But how can I find files by file type?



For example, my-find . -type f -name 'sunrise' -filetype=bash-script:



./astronomy/sunrise
./schedule/sunrise









share|improve this question




















  • 1




    There is no --filetype option for the find command or anything else that will tell you the type of file. The only thing that you can do is use --exec file {} ; and then pipe it into grep Bourne if you were looking for bash scripts or grep Perl if you were looking for Perl scripts or something along those lines.
    – Nasir Riley
    Nov 24 at 14:57

















up vote
8
down vote

favorite
1












I know I can find files using find: find . -type f -name 'sunrise'. Example result:



./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise


I also know that I can determine the file type of a file: file sunrise. Example result:



sunrise: PEM RSA private key


But how can I find files by file type?



For example, my-find . -type f -name 'sunrise' -filetype=bash-script:



./astronomy/sunrise
./schedule/sunrise









share|improve this question




















  • 1




    There is no --filetype option for the find command or anything else that will tell you the type of file. The only thing that you can do is use --exec file {} ; and then pipe it into grep Bourne if you were looking for bash scripts or grep Perl if you were looking for Perl scripts or something along those lines.
    – Nasir Riley
    Nov 24 at 14:57















up vote
8
down vote

favorite
1









up vote
8
down vote

favorite
1






1





I know I can find files using find: find . -type f -name 'sunrise'. Example result:



./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise


I also know that I can determine the file type of a file: file sunrise. Example result:



sunrise: PEM RSA private key


But how can I find files by file type?



For example, my-find . -type f -name 'sunrise' -filetype=bash-script:



./astronomy/sunrise
./schedule/sunrise









share|improve this question















I know I can find files using find: find . -type f -name 'sunrise'. Example result:



./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise


I also know that I can determine the file type of a file: file sunrise. Example result:



sunrise: PEM RSA private key


But how can I find files by file type?



For example, my-find . -type f -name 'sunrise' -filetype=bash-script:



./astronomy/sunrise
./schedule/sunrise






files find file-command file-types






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 at 18:36

























asked Nov 24 at 14:43









Flux

221110




221110








  • 1




    There is no --filetype option for the find command or anything else that will tell you the type of file. The only thing that you can do is use --exec file {} ; and then pipe it into grep Bourne if you were looking for bash scripts or grep Perl if you were looking for Perl scripts or something along those lines.
    – Nasir Riley
    Nov 24 at 14:57
















  • 1




    There is no --filetype option for the find command or anything else that will tell you the type of file. The only thing that you can do is use --exec file {} ; and then pipe it into grep Bourne if you were looking for bash scripts or grep Perl if you were looking for Perl scripts or something along those lines.
    – Nasir Riley
    Nov 24 at 14:57










1




1




There is no --filetype option for the find command or anything else that will tell you the type of file. The only thing that you can do is use --exec file {} ; and then pipe it into grep Bourne if you were looking for bash scripts or grep Perl if you were looking for Perl scripts or something along those lines.
– Nasir Riley
Nov 24 at 14:57






There is no --filetype option for the find command or anything else that will tell you the type of file. The only thing that you can do is use --exec file {} ; and then pipe it into grep Bourne if you were looking for bash scripts or grep Perl if you were looking for Perl scripts or something along those lines.
– Nasir Riley
Nov 24 at 14:57












3 Answers
3






active

oldest

votes

















up vote
13
down vote



accepted










"File types" on a Unix system are things like regular files, directories, named pipes, character special files, symbolic links etc. These are the type of files that find can filter on with its -type option.



The find utility can not by itself distinguish between a "shell script", "JPEG image file" or any other type of regular file. These types of data may however be distinguished by the file utility, which looks at particular signatures within the files themselves to determine their type.



A common way to label the different types of data files is by their MIME type, and file is able to determine the MIME type of a file.





Using file with find to detect the MIME type of regular files, and use that to only find shell scripts:



find . -type f -exec sh -c '
case $( file -bi "$1" ) in
*/x-shellscript*) exit 0
esac
exit 1' sh {} ';' -print


or, using bash,



find . -type f 
-exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';'
-print


Add -name sunrise before the -exec if you wish to only detect scripts with that name.



The find command above will find all regular files in or below the current directory, and for each such file call a short in-line shell script. This script runs file -bi on the found file and exits with a zero exit status if the output of that command contains the string /x-shellscript. If the output does not contain that string, it exits with a non-zero exit status which causes find to continue immediately with the next file. If the file was found to be a shell script, the find command will proceed to output the file's pathname (the -print at the end, which could also be replaced by some other action).



The file -bi command will output the MIME type of the file. For a shell script on Linux (and most other systems), this would be something like



text/x-shellscript; charset=us-ascii


while on systems with a slightly older variant of the file utility, it may be



application/x-shellscript


The common bit is the /x-shellscript substring.



Note that on macOS, you would have to use file -bI instead of file -bi because of reasons (the -i option does something quite different). The output on macOS is similar to that of a Linux system.





Would you want to perform some custom action on each found shell script, you could do that with another -exec in place of the -print in the find commands above, but it would also be possible to do



find . -type f -exec sh -c '
for pathname do
case $( file -bi "$pathname" ) in
*/x-shellscript*) ;;
*) continue
esac

# some code here that acts on "$pathname"

done' sh {} +


or, with bash,



find . -type f -exec bash -c '
for pathname do
[[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

# some code here that acts on "$pathname"

done' bash {} +




Related:




  • Understanding the -exec option of `find`






share|improve this answer






























    up vote
    0
    down vote













    Using perl's File::LibMagic module:



    perl -MFile::LibMagic=:easy -MFile::Find -le '
    find sub {
    print $File::Find::name if
    $_ eq "sunrise" and
    -f and
    MagicFile$_ eq "PEM RSA private key"
    }, @ARGV' -- .





    share|improve this answer




























      up vote
      0
      down vote













      You could exec find on every found file and then grep for the result you're interested in.



      # When looking for ASCII Text
      find . -type -exec file {} ; | grep "ASCII"
      # or for MS Word Documents
      find . -type f -exec file {} ; | grep "Microsoft Word"


      I suggest to make the search pattern as close as possible to your expectation to keep the number of the false positive matches low.



      Beware that files with newlines in their filenames may cause issues with this approach.






      share|improve this answer





















        Your Answer








        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "106"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483871%2fhow-to-find-files-by-file-type%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        13
        down vote



        accepted










        "File types" on a Unix system are things like regular files, directories, named pipes, character special files, symbolic links etc. These are the type of files that find can filter on with its -type option.



        The find utility can not by itself distinguish between a "shell script", "JPEG image file" or any other type of regular file. These types of data may however be distinguished by the file utility, which looks at particular signatures within the files themselves to determine their type.



        A common way to label the different types of data files is by their MIME type, and file is able to determine the MIME type of a file.





        Using file with find to detect the MIME type of regular files, and use that to only find shell scripts:



        find . -type f -exec sh -c '
        case $( file -bi "$1" ) in
        */x-shellscript*) exit 0
        esac
        exit 1' sh {} ';' -print


        or, using bash,



        find . -type f 
        -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';'
        -print


        Add -name sunrise before the -exec if you wish to only detect scripts with that name.



        The find command above will find all regular files in or below the current directory, and for each such file call a short in-line shell script. This script runs file -bi on the found file and exits with a zero exit status if the output of that command contains the string /x-shellscript. If the output does not contain that string, it exits with a non-zero exit status which causes find to continue immediately with the next file. If the file was found to be a shell script, the find command will proceed to output the file's pathname (the -print at the end, which could also be replaced by some other action).



        The file -bi command will output the MIME type of the file. For a shell script on Linux (and most other systems), this would be something like



        text/x-shellscript; charset=us-ascii


        while on systems with a slightly older variant of the file utility, it may be



        application/x-shellscript


        The common bit is the /x-shellscript substring.



        Note that on macOS, you would have to use file -bI instead of file -bi because of reasons (the -i option does something quite different). The output on macOS is similar to that of a Linux system.





        Would you want to perform some custom action on each found shell script, you could do that with another -exec in place of the -print in the find commands above, but it would also be possible to do



        find . -type f -exec sh -c '
        for pathname do
        case $( file -bi "$pathname" ) in
        */x-shellscript*) ;;
        *) continue
        esac

        # some code here that acts on "$pathname"

        done' sh {} +


        or, with bash,



        find . -type f -exec bash -c '
        for pathname do
        [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

        # some code here that acts on "$pathname"

        done' bash {} +




        Related:




        • Understanding the -exec option of `find`






        share|improve this answer



























          up vote
          13
          down vote



          accepted










          "File types" on a Unix system are things like regular files, directories, named pipes, character special files, symbolic links etc. These are the type of files that find can filter on with its -type option.



          The find utility can not by itself distinguish between a "shell script", "JPEG image file" or any other type of regular file. These types of data may however be distinguished by the file utility, which looks at particular signatures within the files themselves to determine their type.



          A common way to label the different types of data files is by their MIME type, and file is able to determine the MIME type of a file.





          Using file with find to detect the MIME type of regular files, and use that to only find shell scripts:



          find . -type f -exec sh -c '
          case $( file -bi "$1" ) in
          */x-shellscript*) exit 0
          esac
          exit 1' sh {} ';' -print


          or, using bash,



          find . -type f 
          -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';'
          -print


          Add -name sunrise before the -exec if you wish to only detect scripts with that name.



          The find command above will find all regular files in or below the current directory, and for each such file call a short in-line shell script. This script runs file -bi on the found file and exits with a zero exit status if the output of that command contains the string /x-shellscript. If the output does not contain that string, it exits with a non-zero exit status which causes find to continue immediately with the next file. If the file was found to be a shell script, the find command will proceed to output the file's pathname (the -print at the end, which could also be replaced by some other action).



          The file -bi command will output the MIME type of the file. For a shell script on Linux (and most other systems), this would be something like



          text/x-shellscript; charset=us-ascii


          while on systems with a slightly older variant of the file utility, it may be



          application/x-shellscript


          The common bit is the /x-shellscript substring.



          Note that on macOS, you would have to use file -bI instead of file -bi because of reasons (the -i option does something quite different). The output on macOS is similar to that of a Linux system.





          Would you want to perform some custom action on each found shell script, you could do that with another -exec in place of the -print in the find commands above, but it would also be possible to do



          find . -type f -exec sh -c '
          for pathname do
          case $( file -bi "$pathname" ) in
          */x-shellscript*) ;;
          *) continue
          esac

          # some code here that acts on "$pathname"

          done' sh {} +


          or, with bash,



          find . -type f -exec bash -c '
          for pathname do
          [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

          # some code here that acts on "$pathname"

          done' bash {} +




          Related:




          • Understanding the -exec option of `find`






          share|improve this answer

























            up vote
            13
            down vote



            accepted







            up vote
            13
            down vote



            accepted






            "File types" on a Unix system are things like regular files, directories, named pipes, character special files, symbolic links etc. These are the type of files that find can filter on with its -type option.



            The find utility can not by itself distinguish between a "shell script", "JPEG image file" or any other type of regular file. These types of data may however be distinguished by the file utility, which looks at particular signatures within the files themselves to determine their type.



            A common way to label the different types of data files is by their MIME type, and file is able to determine the MIME type of a file.





            Using file with find to detect the MIME type of regular files, and use that to only find shell scripts:



            find . -type f -exec sh -c '
            case $( file -bi "$1" ) in
            */x-shellscript*) exit 0
            esac
            exit 1' sh {} ';' -print


            or, using bash,



            find . -type f 
            -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';'
            -print


            Add -name sunrise before the -exec if you wish to only detect scripts with that name.



            The find command above will find all regular files in or below the current directory, and for each such file call a short in-line shell script. This script runs file -bi on the found file and exits with a zero exit status if the output of that command contains the string /x-shellscript. If the output does not contain that string, it exits with a non-zero exit status which causes find to continue immediately with the next file. If the file was found to be a shell script, the find command will proceed to output the file's pathname (the -print at the end, which could also be replaced by some other action).



            The file -bi command will output the MIME type of the file. For a shell script on Linux (and most other systems), this would be something like



            text/x-shellscript; charset=us-ascii


            while on systems with a slightly older variant of the file utility, it may be



            application/x-shellscript


            The common bit is the /x-shellscript substring.



            Note that on macOS, you would have to use file -bI instead of file -bi because of reasons (the -i option does something quite different). The output on macOS is similar to that of a Linux system.





            Would you want to perform some custom action on each found shell script, you could do that with another -exec in place of the -print in the find commands above, but it would also be possible to do



            find . -type f -exec sh -c '
            for pathname do
            case $( file -bi "$pathname" ) in
            */x-shellscript*) ;;
            *) continue
            esac

            # some code here that acts on "$pathname"

            done' sh {} +


            or, with bash,



            find . -type f -exec bash -c '
            for pathname do
            [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

            # some code here that acts on "$pathname"

            done' bash {} +




            Related:




            • Understanding the -exec option of `find`






            share|improve this answer














            "File types" on a Unix system are things like regular files, directories, named pipes, character special files, symbolic links etc. These are the type of files that find can filter on with its -type option.



            The find utility can not by itself distinguish between a "shell script", "JPEG image file" or any other type of regular file. These types of data may however be distinguished by the file utility, which looks at particular signatures within the files themselves to determine their type.



            A common way to label the different types of data files is by their MIME type, and file is able to determine the MIME type of a file.





            Using file with find to detect the MIME type of regular files, and use that to only find shell scripts:



            find . -type f -exec sh -c '
            case $( file -bi "$1" ) in
            */x-shellscript*) exit 0
            esac
            exit 1' sh {} ';' -print


            or, using bash,



            find . -type f 
            -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';'
            -print


            Add -name sunrise before the -exec if you wish to only detect scripts with that name.



            The find command above will find all regular files in or below the current directory, and for each such file call a short in-line shell script. This script runs file -bi on the found file and exits with a zero exit status if the output of that command contains the string /x-shellscript. If the output does not contain that string, it exits with a non-zero exit status which causes find to continue immediately with the next file. If the file was found to be a shell script, the find command will proceed to output the file's pathname (the -print at the end, which could also be replaced by some other action).



            The file -bi command will output the MIME type of the file. For a shell script on Linux (and most other systems), this would be something like



            text/x-shellscript; charset=us-ascii


            while on systems with a slightly older variant of the file utility, it may be



            application/x-shellscript


            The common bit is the /x-shellscript substring.



            Note that on macOS, you would have to use file -bI instead of file -bi because of reasons (the -i option does something quite different). The output on macOS is similar to that of a Linux system.





            Would you want to perform some custom action on each found shell script, you could do that with another -exec in place of the -print in the find commands above, but it would also be possible to do



            find . -type f -exec sh -c '
            for pathname do
            case $( file -bi "$pathname" ) in
            */x-shellscript*) ;;
            *) continue
            esac

            # some code here that acts on "$pathname"

            done' sh {} +


            or, with bash,



            find . -type f -exec bash -c '
            for pathname do
            [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

            # some code here that acts on "$pathname"

            done' bash {} +




            Related:




            • Understanding the -exec option of `find`







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 24 at 20:17

























            answered Nov 24 at 15:17









            Kusalananda

            118k16223362




            118k16223362
























                up vote
                0
                down vote













                Using perl's File::LibMagic module:



                perl -MFile::LibMagic=:easy -MFile::Find -le '
                find sub {
                print $File::Find::name if
                $_ eq "sunrise" and
                -f and
                MagicFile$_ eq "PEM RSA private key"
                }, @ARGV' -- .





                share|improve this answer

























                  up vote
                  0
                  down vote













                  Using perl's File::LibMagic module:



                  perl -MFile::LibMagic=:easy -MFile::Find -le '
                  find sub {
                  print $File::Find::name if
                  $_ eq "sunrise" and
                  -f and
                  MagicFile$_ eq "PEM RSA private key"
                  }, @ARGV' -- .





                  share|improve this answer























                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    Using perl's File::LibMagic module:



                    perl -MFile::LibMagic=:easy -MFile::Find -le '
                    find sub {
                    print $File::Find::name if
                    $_ eq "sunrise" and
                    -f and
                    MagicFile$_ eq "PEM RSA private key"
                    }, @ARGV' -- .





                    share|improve this answer












                    Using perl's File::LibMagic module:



                    perl -MFile::LibMagic=:easy -MFile::Find -le '
                    find sub {
                    print $File::Find::name if
                    $_ eq "sunrise" and
                    -f and
                    MagicFile$_ eq "PEM RSA private key"
                    }, @ARGV' -- .






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 24 at 22:08









                    Stéphane Chazelas

                    296k54559902




                    296k54559902






















                        up vote
                        0
                        down vote













                        You could exec find on every found file and then grep for the result you're interested in.



                        # When looking for ASCII Text
                        find . -type -exec file {} ; | grep "ASCII"
                        # or for MS Word Documents
                        find . -type f -exec file {} ; | grep "Microsoft Word"


                        I suggest to make the search pattern as close as possible to your expectation to keep the number of the false positive matches low.



                        Beware that files with newlines in their filenames may cause issues with this approach.






                        share|improve this answer

























                          up vote
                          0
                          down vote













                          You could exec find on every found file and then grep for the result you're interested in.



                          # When looking for ASCII Text
                          find . -type -exec file {} ; | grep "ASCII"
                          # or for MS Word Documents
                          find . -type f -exec file {} ; | grep "Microsoft Word"


                          I suggest to make the search pattern as close as possible to your expectation to keep the number of the false positive matches low.



                          Beware that files with newlines in their filenames may cause issues with this approach.






                          share|improve this answer























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            You could exec find on every found file and then grep for the result you're interested in.



                            # When looking for ASCII Text
                            find . -type -exec file {} ; | grep "ASCII"
                            # or for MS Word Documents
                            find . -type f -exec file {} ; | grep "Microsoft Word"


                            I suggest to make the search pattern as close as possible to your expectation to keep the number of the false positive matches low.



                            Beware that files with newlines in their filenames may cause issues with this approach.






                            share|improve this answer












                            You could exec find on every found file and then grep for the result you're interested in.



                            # When looking for ASCII Text
                            find . -type -exec file {} ; | grep "ASCII"
                            # or for MS Word Documents
                            find . -type f -exec file {} ; | grep "Microsoft Word"


                            I suggest to make the search pattern as close as possible to your expectation to keep the number of the false positive matches low.



                            Beware that files with newlines in their filenames may cause issues with this approach.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 29 at 14:01









                            Rolf

                            4801510




                            4801510






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483871%2fhow-to-find-files-by-file-type%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Quarter-circle Tiles

                                build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

                                Mont Emei