find

From RaySoft

find is a command-line utility that searches through one or more directory trees of a file system, locates files based on some user-specified criteria and applies a user-specified action on each matched file. The possible search criteria include a pattern to match against the file name or a time range to match against the modification time or access time of the file. By default, find returns a list of all files below the current working directory.[1]

Documentation

Syntax

find PATH [PATH ...] [PARAMETER ...]

Parameters

Global

-depth
Process each directory's contents before the directory itself. Doing this is a good idea when producing lists of files to archive with cpio or tar. If a directory does not have write permission for its owner, its contents can still be restored from the archive since the directory's permissions are restored after its contents.
-maxdepth LEVEL
Descend at most LEVEL (a non-negative integer) levels of directories below the command line arguments. -maxdepth 0 means only apply the tests and actions to the command line arguments.
-mindepth LEVEL
Do not apply any tests or actions at levels less than LEVEL (a non-negative integer). -mindepth 1 means process all files except the command line arguments.

Tests

-empty
True if the file is empty and is either a regular file or a directory. This might help determine good candidates for deletion.
-group NAME
File belongs to group NAME (numeric group ID allowed).
-name PATTERN, -iname PATTERN
True if the base of the file name (the path with the leading directories removed) matches shell pattern PATTERN. For -iname, the match is case-insensitive.
-path PATTERN, -ipath PATTERN
True if the entire file name, starting with the command line argument under which the file was found, matches shell pattern PATTERN. For -ipath, the match is case-insensitive.
-regex PATTERN, -iregex PATTERN
True if the entire file name matches regular expression PATTERN. This is a match on the whole path, not a search. For -iregex, the match is case-insensitive.
-perm MODE
File's permission bits are exactly MODE (octal or symbolic). Since an exact match is required, if you want to use this form for symbolic modes, you may have to specify a rather complex mode string.
-perm -MODE
All of the permission bits MODE are set for the file. Symbolic modes are accepted in this form, and this is usually the way in which would want to use them. You must specify u, g or o if you use a symbolic mode.
-perm /MODE
Any of the permission bits MODE are set for the file. Symbolic modes are accepted in this form. You must specify u, g or o if you use a symbolic mode.
-type TYPE
True if the file is of type TYPE:
  • b for block (buffered) special
  • c for character (unbuffered) special
  • d for directory
  • p for named pipe (FIFO)
  • f for regular file
  • l for symbolic link; this is never true if the -L option or the -follow option is in effect, unless the symbolic link is broken
  • s for socket
-user NAME
File is owned by user NAME (numeric user ID allowed).

Actions

-delete
Delete files or directories; true if removal succeeded. If the removal failed, an error message is issued.
The use of the -delete action on the command line automatically turns on the -depth option.
-exec COMMAND {} ;
Execute COMMAND; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ; is encountered. The string {} is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a \) or quoted to protect them from expansion by the shell.
-exec COMMAND {} +
This variant of the -exec action runs the specified COMMAND on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files.
-execdir COMMAND {} ;|+
Execute COMMAND true if zero status is returned. find takes all arguments after -execdir to be part of the command until an argument consisting of ; is reached. It replaces the string {} by the current file name being processed everywhere it occurs in the command. Both of these constructions need to be escaped (with a \) or quoted to protect them from expansion by the shell. The command is executed in the directory in which find was run.
The + form of -execdir will build a command line to process more than one matched file, but any given invocation of command will only list files that exist in the same subdirectory.
-print
True; print the entire file name on the standard output, followed by a newline. If there is the faintest possibility that one of the files for which you are searching might contain a newline, you should use -print0 instead.
-print0
True; print the entire file name on the standard output, followed by a null character \0.
-printf FORMAT
Print FORMAT on the standard output.
%f
File's name with any leading directories removed (only the last element).
%g
File's group name, or numeric group ID if the group has no name.
%G
File's numeric group ID.
%h
Leading directories of file's name (all but the last element). If the file name contains no slashes (since it is in the current directory) the %h specifier expands to ..
%m
File's permission bits (in octal). Normally you will want to have a leading zero on this number, and to do this, you should use the # flag (as in, for example, %#m).
%M
File's permissions (in symbolic form, as for ls).
%p
File's name.
%u
File's user name, or numeric user ID if the user has no name.
%U
File's numeric user ID.
-prune
If the file is a directory, do not descend into it. The result is true.

Operators

Listed in order of decreasing precedence:

( EXPRESSION )
Force precedence. True if EXPRESSION is true.
! EXPRESSION
-not EXPRESSION
True if EXPRESSION is false. In some shells, it is necessary to protect the ! from shell interpretation by quoting it.
EXPRESSION1 EXPRESSION2
EXPRESSION1 -a EXPRESSION 2
EXPRESSION1 -and EXPRESSION2
And; EXPRESSION2 is not evaluated if EXPRESSION1 is false.
EXPRESSION1 -o EXPRESSION2
EXPRESSION1 -or EXPRESSION2
Or; EXPRESSION2 is not evaluated if EXPRESSION1 is true.
EXPRESSION1 , EXPRESSION2
List; both EXPRESSION1 and EXPRESSION2 are always evaluated. True if EXPRESSION2 is true. The value of EXPRESSION1 is discarded. This operator lets you do multiple independent operations on one traversal, without depending on whether other operations succeeded. The two operations EXPRESSION1 and EXPRESSION2 are not always fully independent, since EXPRESSION1 might have side effects like touching or deleting files, or it might use -prune which would also affect EXPRESSION2.

Examples

Find all files with the extension 'tmp' and delete them
find "${HOME}" -type 'f' -name '*.tmp' -delete
Change all permissions in the user's home directory
find "${HOME}" '(' -type 'd' -execdir chmod --changes 0700 '{}' '+' ')' \
           -or '(' -type 'f' -execdir chmod --changes 0600 '{}' '+' ')'
Set all permissions but ignore the bin directory using -prune
find '.' -type 'd' -execdir chmod 1775 '{}' '+'
find '.' -path './bin' -prune \
         -or -type 'f' -execdir chmod 0644 '{}' '+'
find './bin' -type 'f' -execdir chmod 0755 '{}' '+'
Only sync files which are older than 30 days
[[ -d "${bkp_path}" ]] || mkdir -p "${bkp_path}"

find "${src_path}" -type 'f' -mtime '+30' -print0 \
| sed --null-data "s|${src_path%/*}/||" \
| rsync --archive --from0 --files-from=- --verbose "${src_path%/*}" "${bkp_path}"
Work with German special characters (like äöü) in the macOS' file system HFS+
pattern="$(iconv --to-code='UTF-8-MAC' <<<'ausrüstung.md')"

find "${HOME}" -type 'f' -name "*/${pattern}"
NOTE:
UTF-8-MAC is a special encoding which is only available on macOS.
Print results of a search with a prefix
find . -type 'f' -printf 'path = %p'

References