find

Table of Contents

How find works discussion

find [file...] [expression]

An [expression] can contain any of the following types of primaries:

options
affect overall operation rather than the processing of a specific file;
tests
return a true or false value, depending on the file's attributes
actions
have side effects and return a true or false value
operators
connect the other arguments and affect when and whether they are evaluated.

find searches the directory tree rooted at each file name by evaluating the expression from left to right, according to the rules of precedence, *until the outcome is known*(kind of short-circuit evaluation), at which point find moves on to the next file name.

The operators are, in order of decreasing precedence:

find reference

-L
  • causes find to follow symlinks for all properties except the name
  • Because the name cannot be ignored when doing directory search
-o, -or, -a, -and
  • When expressions are placed without any of theses, -and is implied
--empty
  • True if the current file or directory is empty.

Find and delete empty directories howto

find . -type d -empty -not -path './.git/**'
find . -type d -empty -not -path './.git/**' -delete

Delete all broken symbolic links howto

find -L "$HOME" -maxdepth 1 -type l -exec rm {} +
#     │              │            │             └─ cause 'rm path1 path2' not 'rm path1' 'rm path2'
#     │              │            + symbolic link
#     │              + descend at most n directory levels
#     │                in other words, just find in current directory
#     └─ follow symlinks, the link itself if the link target doens't exist

find -exec \; vs find -exec + discussion

-exec ends with \;
Run a grep command for each found file
-exec ends with +
Run a grep command for all found files at once
foo.txt
apple
banana
orange
bar.txt
lemon
lime
orange
find . -name '*.txt' -exec grep orange {} \;
orange
orange
find . -name '*.txt' -exec grep orange {} +
./foo.txt:orange
./bar.txt:orange

Exclude a directory in find howto

find . -path ./misc -prune -o -name '*.txt' -print
find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print

Note that the exclusion test primaries are placed before -prune, followed by -o and the actual action(-print, in this case). As find evaluates the primaries as a short-circuit fashion, the -prune is not evaluated if the preceding expression(-path something) is not true. In this case, primaries following -o will be evaluated.