Find

find(1) is a file finder.


Installation

find(1) will be pre-installed on any Linux or BSD operating system, as a POSIX utility.


Usage

Basic usage:

find . -name '*.zip'

The pattern is a glob shell expression, not a regular expression pattern. The options available are:

But to ensure that the glob is not eagerly evaluated by the shell, the pattern must be quoted.

Furthermore, note that the pattern is checked against the basename of the directory entry. The only possible match to a pattern that includes a / is the root directory itself.

Options

Options

Meaning

Example

-name 'pattern'

Filter to entries with a basename matching a pattern

-name '*.zip'

-type [df]

Filter to files or directories

-type f

-user name

Filter to entries owned by a user

-user root

-group name

Filter to entries owned by a group

-group root

-perm octal

Filter to entries with specific permissions

-perm 775

-not

Invert a subsequent filter

-not -perm 775

-mindepth int

Only search subdirectories some layers deep

-mindepth 1

-maxdepth int

Stop searching subdirectories at some layers deep

-maxdepth 1

-mindepth and -maxdepth are global options, so must precede any other options.

$ find . -name '*.txt' -maxdepth 1
find: warning: you have specified the global option -maxdepth after the argument -name, but global options are not positional, i.e., -maxdepth affects tests specified before it as well as those specified after it.  Please specify global options before other arguments.
$ find . -maxdepth 1 -name '*.txt'
[trim]

Command Execution

find(1) can execute a command on all still-matching files.

  1. The -exec option consumes all subsequent arguments up to an escaped delimiter, i.e. \;.

  2. If one of those arguments contains {}, that is expanded into the filename.

    • Note that there should only be one {}. Behavior for additional instances is undefined, non-portable, and unsupported.

  3. The arguments are executed in a subshell.
    • Note then that any environmental variables and functions are not shared.
  4. The return code of the subshell determines if the option is considered a match or non-match

The -exec option can be used to implement custom filters. For example:

find somedir -name '' -exec grep --fixed-strings '<!--nomin-->' --quiet {} \;

The -exec option can also be used for scripting, to execute some action on all matches. For example:

Try:

find somedir -name '*.min.js' -exec cp {} ../production/ \;


Tips

find(1) operates from the working directory and prints filenames accordingly. That is...

Furthermore, any subshells started by the -exec option operate in the working directory.

This can be tricky and inconvenient for scripting. Consider:

  1. Always call with an absolute directory. For example: find "$(realpath somedir) ...

  2. Change directory instead of passing a directory. For example: cd somedir && find . ...

  3. Check if your find(1) implementation supports the -execdir option. This flag mirrors -exec except that...

    • if a file is matched, the execution occurs in the same directory as that file.
    • if a directory is matched, the execution occurs in the parent directory.

find(1) should never be piped directly into another command. If the -exec option is insufficient, the safe ways to use the output of find(1) are:

while IFS= read -r -d '' file; do
    echo "$file"
done < <(find . -name '*.zip' -print0)

find . -name '*.zip' -print0 | xargs -0 echo


See also

find(1)


CategoryRicottone

Find (last edited 2024-12-28 15:42:20 by DominicRicottone)