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
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:
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:
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 wherec
can be:f
for regular filed
for directoryl
for symbolic linkb
for block devicec
for character devices
for socketp
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
– bytesk
– kilobytes (1024 bytes)M
– megabytesG
– gigabytes
Modifiers:
+n
: Greater than n.-n
: Less than n.
Examples:
Find files exactly 100 kilobytes:find . -size 100kFind 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 withxargs -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" -deleteNote:
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:
Here’s what happens:
-path "./node_modules" -prune
tellsfind
to skip thenode_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:
Example 2: Find Files Modified in the Last 2 Days
Example 3: Find and Delete Empty Files
Example 4: Find Files Larger Than 100 MB
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:
Example 6: Execute a Command on Each File
Find all .log
files and compress them using gzip
:
Example 7: Combining Criteria with Parentheses
Find files that are either .conf
or .cfg
files:
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 deepfind
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 withxargs -0
to correctly handle file names containing spaces, newlines, or other special characters.Testing Before Running Actions:
Always test yourfind
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
Manual Pages:
Check out the manual page for detailed information:man findOnline Tutorials and Guides:
Books and Articles:
Look for system administration and shell scripting books that coverfind
in depth.
By experimenting with various options and integrating find
into your scripts, you can unlock a new level of efficiency in file management. Happy finding!