AICollection Help

find

The find command is one of the most powerful and flexible tools available on Unix-like systems for searching and manipulating files and directories. It allows you to search for files based on a wide range of criteria—such as name patterns, file types, sizes, modification times, permissions, ownership, and more—and then perform actions on the matching files. In this article, we’ll dive deep into the find command, explain its syntax and options, and provide plenty of examples to help you harness its full potential.

Table of Contents

  1. Introduction

  2. Basic Syntax and How find Works

  3. Common Search Criteria

  4. Combining Criteria with Logical Operators

  5. Actions: What to Do with Matched Files

  6. Performance Considerations: Pruning Directories

  7. Practical Examples

  8. Advanced Usage and Tips

  9. Conclusion and Further Reading

Introduction

The find command is a versatile search utility that recursively traverses directory trees to locate files that meet specified conditions. Its flexibility makes it an indispensable tool for system administration, scripting, and everyday file management tasks. Whether you need to locate outdated backups, find large log files, or apply batch changes to a set of files, find provides the power and precision required.

Basic Syntax and How find Works

The general syntax of the find command is:

find [starting-point...] [expression]
  • Starting-point(s): The directories where find will begin its search (e.g., /, /home, .). If you don’t specify a starting point, the current directory is used.

  • Expression: A series of options, tests, and actions that define what files to search for and what to do with them. These are evaluated from left to right.

Example:

find /home/user -name "report.txt"

This command searches for files named report.txt starting from /home/user and prints the full path of each match.

Common Search Criteria

Name and Pattern Matching

  • -name pattern
    Matches files (or directories) with names that exactly match the given shell pattern. The match is case-sensitive.

    find . -name "example.txt"
  • -iname pattern
    Similar to -name but case-insensitive.

    find /var/log -iname "syslog*"
  • -regex pattern
    Uses a regular expression to match the entire path.

    find . -regex ".*[0-9]{4}\.log"

File Types

  • -type c
    Filters files by type where c can be:

    • f for regular file

    • d for directory

    • l for symbolic link

    • b for block device

    • c for character device

    • s for socket

    • p for named pipe (FIFO)

    Example:
    Find all directories in /etc:

    find /etc -type d

File Size

  • -size n
    Finds files based on size. The size can be specified in:

    • c – bytes

    • k – kilobytes (1024 bytes)

    • M – megabytes

    • G – gigabytes

    Modifiers:

    • +n: Greater than n.

    • -n: Less than n.

    Examples:
    Find files exactly 100 kilobytes:

    find . -size 100k

    Find files larger than 10 megabytes:

    find /var -size +10M

Time-Based Criteria

  • -mtime n
    Matches files modified exactly n days ago.

    • +n: More than n days ago.

    • -n: Less than n days ago.

    Example:
    Find files modified in the last 7 days:

    find . -mtime -7
  • -atime n
    Matches files accessed n days ago (same modifiers as above).

  • -ctime n
    Matches files with a status change (permissions, ownership, etc.) n days ago.

Ownership and Permissions

  • -user username
    Finds files owned by the specified user.

    find /home -user alice
  • -group groupname
    Finds files belonging to the specified group.

  • -perm mode
    Matches files with the specified permissions.
    You can specify:

    • Exact permissions (e.g., 644)

    • Symbolic modes (e.g., /u=r for “user has read permission”)

    Example:
    Find files that are world-writable:

    find /tmp -perm -o+w

Combining Criteria with Logical Operators

The find command allows you to combine multiple tests using logical operators:

  • AND (-a) is implicit between tests.

    find . -type f -name "*.log"
  • OR (-o) explicitly combine tests that match either condition. When using OR, it is usually a good idea to group tests with parentheses (escaped or quoted):

    find /var -type f \( -name "*.log" -o -name "*.txt" \)
  • NOT (! or -not) negates a test:

    find . -not -name "*.bak"

Parentheses are used to group expressions; they must be escaped or quoted to prevent shell interpretation.

Actions: What to Do with Matched Files

After filtering files, you can perform actions on them. If no action is specified, find prints the file names (this is equivalent to -print).

Printing the Results

  • -print
    Explicitly prints the matched file paths. (Often implicit.)

    find . -type f -name "*.conf" -print
  • -print0
    Prints the file names followed by a null character. This is useful for handling files with spaces or special characters and is often paired with xargs -0.

    find . -type f -print0 | xargs -0 ls -l

Executing Commands with -exec and -ok

  • -exec command {} \;
    Executes a command on each file found. The {} placeholder is replaced with the current file name.

    Example:
    Delete all temporary files:

    find . -name "*.tmp" -exec rm {} \;
  • -exec command {} +
    Similar to -exec but builds a command line with multiple file names at once, which can be more efficient.

    find . -name "*.log" -exec grep "ERROR" {} +
  • -ok command {} \;
    Similar to -exec but asks for user confirmation before executing the command on each file.

Deleting Files

  • -delete
    Deletes files that match the criteria. Use with caution because this action cannot be undone.

    find . -name "*.bak" -delete

    Note:
    The -delete option must appear after all tests, and it implies -depth (i.e., it processes files before their parent directories).

Performance Considerations: Pruning Directories

When searching in directories that contain many files or subdirectories, you might want to exclude some directories from the search. The -prune option helps you do that.

Example:
Exclude the node_modules directory:

find . -path "./node_modules" -prune -o -type f -name "*.js" -print

Here’s what happens:

  • -path "./node_modules" -prune tells find to skip the node_modules directory.

  • -o (OR) allows the subsequent tests to apply to files not pruned.

  • The -print action is executed only on files that match the remaining criteria.

Practical Examples

Example 1: Find Files by Name

Search for all .txt files in your home directory:

find ~/ -type f -name "*.txt"

Example 2: Find Files Modified in the Last 2 Days

find /var/log -type f -mtime -2

Example 3: Find and Delete Empty Files

find . -type f -empty -delete

Example 4: Find Files Larger Than 100 MB

find / -type f -size +100M 2>/dev/null

Note: Redirecting errors (2>/dev/null) helps avoid permission-denied messages.

Example 5: Search by Ownership and Permission

Find all files owned by user alice that are world-writable:

find /home/alice -user alice -perm -o+w

Example 6: Execute a Command on Each File

Find all .log files and compress them using gzip:

find /var/log -type f -name "*.log" -exec gzip {} \;

Example 7: Combining Criteria with Parentheses

Find files that are either .conf or .cfg files:

find /etc \( -name "*.conf" -o -name "*.cfg" \)

Advanced Usage and Tips

  • Using Regular Expressions:
    The -regex option provides advanced pattern matching capabilities. Remember that the regular expression must match the entire path, not just the file name.

  • Optimizing Searches:

    • Use -prune to exclude directories that are not needed.

    • Use -maxdepth and -mindepth to control how deep find searches in the directory tree.

    Example:
    Limit the search to the current directory only (no recursion):

    find . -maxdepth 1 -type f -name "*.sh"
  • Handling Special Characters:
    Use -print0 in conjunction with xargs -0 to correctly handle file names containing spaces, newlines, or other special characters.

  • Testing Before Running Actions:
    Always test your find command without destructive actions (like -delete or -exec rm) to ensure it is selecting the correct files. Replace these actions with -print first.

Conclusion and Further Reading

The find command is an essential tool for anyone who works with Unix-like systems. Its ability to search for files based on nearly any criterion and perform batch operations on those files makes it indispensable for system administration, scripting, and file management. By mastering find ’s syntax, options, and combining logical expressions, you can save time and increase your productivity when managing files.

Further Reading and Resources

By experimenting with various options and integrating find into your scripts, you can unlock a new level of efficiency in file management. Happy finding!

Last modified: 08 February 2025