findThe command find searches the filesystem for files based on their metadata.
The metadata that can be used to search for files includes, but is not limited
to a file’s:
Unlike search mechanisms found outside a terminal (like Window Search or Apple’s
Spotlight) which only list the files found, find can do things to the files it
finds. The tasks you can have find do are limited only by your imagination.
The syntax for find is:
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
but the key to using find is in the path and expression arguments, which can be complex.
The optional path arguments tell find where to begin looking for files. If
not given, the current directory is used.find will ordinarily enter
subdirectories, but not parent directories of the given paths.
A good practice is to explicitly enter the path . to search the current
directory, even though it is the default path.
The expression is made up of option switches, tests, and actions, each
separated by an operator. The format of these expression elements varies, and
are fully documented in the manual page man find. There are too many
expression elements to cover here, but below are listed the ones that we think are
the most useful or noteworthy.
Options affect the behavior of find as a whole. Commonly used options include:
-depthDeleting directories requires they be empty, so some actions like -delete
will imply -depth automatically.
-maxdepth LEVELDo not confuse -maxdepth with -depth: they have completely different
behaviours and uses.
-mindepth LEVEL-helpTests are used to compare a file against some reference. If the test comparison
yields true, the next test or action in the expression (read left to right) is
applied. If a test yields false, find moves on to the next file. Commonly used
tests include:
-name PATTERN-iname PATTERN-name is
case-sensitive, whereas -iname is case-insensitive. The PATTERN can
include wildcard characters.Common wildcards include:
* which matches any number of any characters,
? which matches one position of any character, and
[ EXPR ] will match a POSIX bracket expression in one position.
The syntax for bracket expressions is beyond the scope of this tutorial but
we’ll see some examples of what they look like.
-regex REGEXPRegular expressions are an extremely powerful means of matching patterns. They are used in many places and are worth learning, but deserve a treatment in their own right.
-size n[bcwkMG]-readable-writeable-executable-type cc where c is typically one ofd for directory,f for regular file, orl for symbolic link. Other types also exits.-mtime [+-]N-ctime [+-]N-atime [+-]N+ (-), times greater (less) than N days ago are
matched.Actions do something, either emit a response from find or run an arbitrary
command on a matched file. By default, find does the action -print when it
matches a file, which prints the full file name (with path starting from a
path argument) separated by a new line. Commonly used actions include:
-exec CMD {};-execdir CMD {};CMD. The command can be
anything. All arguments following -exec are assumed to be part of the
command until the first occurance of ;. The (optional) characters {}, if
encountered in the command expression, are replaced with the path to the
currently examined file. If you used -execdir, find will run the command
from the subdirectory containing the matched file.-ok CMD ;-exec but prompts the user before executing the command. Very useful
if your expression may alter the file. It cannot take {} to represent the
current matched file, so use it in conjunction with -exec as needed for
safety.-print-printf FORMAT-quit-pruneOperators group expression elements together and allow for logic matching. The operators, in decending order of precedence, are:
( EXPR )! EXPR-not EXPREXPR1 EXPR2EXPR1 -a EXPR2EXPR1 -and EXPR2By default, if two expressions are given without an operator joining them, the
operator -and is assumed.
EXPR1 -o EXPR2EXPR1 -or EXPR2EXPR1 , EXPR2Be mindful of the Spaces surrounding everything! Each of the
expression elements is technically a command argument. As said earlier, all
arguments must be separated by a space. This includes ( and )
Many shells treat the characters *[]{}()?$ amongst others as special
operators. To prevent your shell from altering any input to find, wrap
expressions in quotations as necessary. If in doubt, use quotes.
Print all regular files named exactly “.bashrc” within and below ~:
$ find ~ -type f -name bash.rc
Print all regular files ending in “rc” within ~ and below:
$ find ~ -type f -name "*rc"
Print all files (regular and directories) ending in “rc” within ~:
$ find ~ -name "*rc"
Print only directories one level into /etc that are 3 characters
long which end with “sh” or “sl”
$ find /etc -maxdepth 1 -type d -name "?s[hl]"
Find all files in ~ ending with “.jpg” or “.png” in any case that were created
within the last 2 days.
$ find ~ -type f \( -iname "*.jpg" -or -iname "*.png" \) -and -ctime -2
Find all the files strictly in /tmp named “data_NN.dat” where NN runs from
00-99 and run the command ls -l FILE on each of them:
$ find /tmp -maxdepth 1 -type f -iname "data_[0-9][0-9].dat" -execdir ls -l {} \;
Have you ever needed to analyze hundreds of data files? Imagine if instead of
calling ls on these files, you called a program that you wrote to analyze that
data. This is a quick way to generate those hundreds of plots you need to
process from your research data.