linux - list/find all regular files in all subdirectories excluding binary files

08
2014-07
  • Samer Buna

    In Linux.

    I know I can do find . -type f, but that includes binary file and I couldn't find a way to exclude them with find

  • Answers
  • Dennis Williamson

    file /usr/bin/file, for example, does not include the word "binary" in its output on my system. If file -i is available, it does include the word "binary". Without -i, it may be more reliable to test for the presence of the word "text".

    find -type f -exec sh -c "file {} | grep text >/dev/null" \; -print
    

    or

    find -type f -exec sh -c "file {} | grep text >/dev/null" \; -ls
    

    Using -i:

    find -type f -exec sh -c "file -i {} | grep -v binary >/dev/null" \; -print
    

    Using file is only going to be an approximation since it's using heuristics to determine the type of file and there's no hard-and-fast definition of what constitutes a "binary" file. Is an empty file "binary"? file says it is. Also, there are lots of (normally uncommon) ways to trigger false positive IDs by file.

  • phoibos

    Another way would be to exclude all files which have execute permission set for either user, group or others:

    find . -type f ! -perm /u=x,g=x,o=x
    

    (If binary equals execute permissions...)

  • MaQleod

    show all files without executable permissions (although this is not specifically binary, so it may not be exactly what you need):

    ls -l | awk '{if ($1 !~ /x/) print $8}'
    
  • user31894
    find . -type f -exec file "{}" | grep -vE "ELF|archive"
    

  • Related Question

    linux - Delete matching files in all subdirectories
  • Alex

    How can I remove all .swp files in all of my subdirectories under Linux?


  • Related Answers
  • quack quixote

    Remove all *.swp files underneath the current directory, use the find command in one of the following forms:

    • find . -name \*.swp -type f -delete

      The -delete option means find will directly delete the matching files. This is the best match to OP's actual question.

      Using -type f means find will only process files.

    • find . -name \*.swp -type f -exec rm -f {} \;
      find . -name \*.swp -type f -exec rm -f {} +

      Option -exec allows find to execute an arbitrary command per file. The first variant will run the command once per file, and the second will run as few commands as possible by replacing {} with as many parameters as possible.

    • find . -name \*.swp -type f -print0 | xargs -0 rm -f

      Piping the output to xargs is used form more complex per-file commands than is possible with -exec. The option -print0 tells find to separate matches with ASCII NULL instead of a newline, and -0 tells xargs to expect NULL-separated input. This makes the pipe construct safe for filenames containing whitespace.

    See man find for more details and examples.

  • Jonathan Leffler

    find . -name '*.swp' -delete

    Having find do the delete itself remove any risk for space embedded in filename, ... For extra security also consider adding -type f for files only.

  • user31894
    find /path -type f -name "*.swp" -delete
    find /path -type f -name "*.swp" -exec rm -f "{}" +;
    

    bash 4.0

    shopt -s globstar
    rm -f /path/**/*.swp