LinuxCommandLibrary

find

Find files and directories

TLDR

Find files by extension

$ find [root_path] -name '[*.ext]'
copy

Find files matching multiple path/name patterns
$ find [root_path] -path '[*/path/*/*.ext]' -or -name '[*pattern*]'
copy

Find directories matching a given name, in case-insensitive mode
$ find [root_path] -type d -iname '[*lib*]'
copy

Find files matching a given pattern, excluding specific paths
$ find [root_path] -name '[*.py]' -not -path '[*/site-packages/*]'
copy

Find files matching a given size range, limiting the recursive depth to "1"
$ find [root_path] -maxdepth 1 -size [+500k] -size [-10M]
copy

Run a command for each file (use {} within the command to access the filename)
$ find [root_path] -name '[*.ext]' -exec [wc -l] {} \;
copy

Find all files modified today and pass the results to a single command as arguments
$ find [root_path] -daystart -mtime [-1] -exec [tar -cvf archive.tar] {} \+
copy

Search for either empty files or directories and delete them verbosely
$ find [root_path] -type [f|d] -empty -delete -print
copy

SYNOPSIS

find [-H | -L | -P] [-Olevel] [-D debuglevel] [path...] expression

PARAMETERS

-H
    Dereference symlinks on command line only.

-L
    Follow symlinks encountered during traversal.

-P
    Never follow symlinks (default).

-Olevel
    Optimize with optimization level.

-D debuglevel
    Enable debug output at specified level.

-daystart
    Measure times from today's start (not 24h ago).

-depth
    Process directories after contents (post-order).

-domain name
    Restrict to specified domain.

-ignore_readdir_race
    Ignore readdir race conditions.

-maxdepth levels
    Descend at most n directory levels.

-mindepth levels
    Act only after descending n levels.

-mount / -xdev
    Stay within one filesystem.

-no_leaf_check
    Disable leaf directory optimization.

-pathdirs
    Use full path for regex matching.

-prune
    Prevent descending into matching directories.

-regex pattern
    Match full path with regex.

-s
    Sort output by filename.

-source path
    Use given path as source.

-type c
    File is of type c (f,d,l, etc.).

-name pattern
    Base name matches shell pattern.

-iname pattern
    Case-insensitive -name.

-size n[c]
    File size is n units.

-mtime n
    Modified n*24h days ago.

-user name
    Owned by user name or ID.

-perm mode
    Permissions match mode.

-exec command {} \;
    Execute command on matches.

-delete
    Delete matching files (use with caution).

-print
    Print pathnames (default action).

-ls
    List in ls -ils format.

!
    Negate preceding expression.

-and / -a
    Logical AND (default).

-or / -o
    Logical OR.

DESCRIPTION

The find command is a versatile Unix/Linux utility for recursively searching files and directories within specified paths based on criteria like name, size, type, permissions, timestamps, ownership, and content. It evaluates an expression consisting of tests, operators, and actions, printing matching paths by default.

Key strengths include precise filtering (e.g., find . -name '*.log' -mtime +7 for logs older than a week) and actions like executing commands (-exec), deleting (-delete), or listing details (-ls). Options control traversal, such as limiting depth (-maxdepth) or handling symlinks (-L).

Essential for sysadmins, find aids backups, cleanup, auditing, and scripting. Combined with xargs or grep, it handles complex tasks efficiently. However, on vast filesystems, it can be slow without optimizations like -xdev to restrict filesystems.

Its expression syntax supports logical operators (-and, -or, !), grouping with parentheses, and positional evaluation left-to-right, offering immense power for file management.

CAVEATS

find can consume high CPU/memory on large directories; use -maxdepth, -xdev. Risky with -delete or -exec rm—test first. Symlink loops possible without -L/-P. Expressions evaluated left-to-right; order matters.

COMMON EXAMPLES

find /home -name '*.tmp' -delete
find . -type f -size +10M -exec ls -lh {} \;
find /var/log -name '*error*' -mtime -1

PERFORMANCE TIPS

Start searches from specific dirs, not /. Use -path or -prune early to skip subtrees. Pipe to xargs -0 for large result sets. Prefer locate for indexed fast searches.

HISTORY

Originated in AT&T Unix Version 7 (1979). GNU find from findutils package since 1990, version 4.0 standardized modern syntax (1993). Continuously enhanced for performance, regex support, and portability.

SEE ALSO

locate(1), updatedb(1), xargs(1), grep(1), ls(1), stat(1)

Copied to clipboard