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

find(1) searches a directory for any files that match patterns and/or rules.

To search for files by name, try:

find somedir -name '*.zip'

The pattern is a glob shell expression, so options available are:

It is not a regular expression pattern.

Furthermore, note that the pattern is checked against the basename of the file; the directory components of the path are not checked. As a result, the only file that can ever match a pattern that includes a / is the root directory itself.

Search by File Type

To search for only files, try:

find somedir -name '*.zip' -type f

Conversely, use -type d to search for only directories.

Search by File Ownership

To search for files by ownership, try:

find somedir -user foo -exec chown bar {} \;

To search for files by group, try:

find somedir -group foo -exec chgrp bar {} \;

Search by File Permissions

To search for files by permissions, try:

find somedir -type d -perm 755

Conversely, to search for files with any other permissions, try:

find somedir -type f -not -perm 644 -exec chmod 644 {} \;

Command Execution

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

  1. The -exec flag consumes everything following the flag up to an escaped delimiter, i.e. \;.

  2. If that string contains a {}, that is expanded into the matching filename.

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

  3. The string is then evaluated as a command and executed in a subshell.
    • Note then that any environmental variables and functions are not shared.

Try:

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

Multiple commands can be chained, i.e. the second command only executes if the first command exits with a success code (0).

find somedir -name '' -exec grep -F '<!--nomin-->' --quiet {} \; -exec cp {} ../production/ \;

Programming Tips

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

Furthermore, any subshells started for -exec flags also operate in the working directory.

These details can be inconvenient for whenever commands depend on proximate files, or for when the output will be parsed as text data.

  1. Some issues can be alleviated by always calling with an absolute directory. Try:
    • find "$(realpath somedir)"
  2. Other issues can be alleviated by always calling with the current directory. Try:
    • cd somedir && find .
  3. Some implementations support -execdir. 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.
    • This inconsistency in behavior can lead to subtle issues. Use with caution, and consider adding a -type f pattern as well. More generally, this is a code smell; consider redesigning the approach.


See also

find(1)


CategoryRicottone

Find (last edited 2024-09-16 15:03:35 by DominicRicottone)