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
findwill 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-namebut 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 whereccan be:ffor regular filedfor directorylfor symbolic linkbfor block devicecfor character devicesfor socketpfor 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=rfor “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-execbut 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-execbut 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-deleteoption 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" -prunetellsfindto skip thenode_modulesdirectory.-o(OR) allows the subsequent tests to apply to files not pruned.The
-printaction 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-regexoption provides advanced pattern matching capabilities. Remember that the regular expression must match the entire path, not just the file name.Optimizing Searches:
Use
-pruneto exclude directories that are not needed.Use
-maxdepthand-mindepthto control how deepfindsearches 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-print0in conjunction withxargs -0to correctly handle file names containing spaces, newlines, or other special characters.Testing Before Running Actions:
Always test yourfindcommand without destructive actions (like-deleteor-exec rm) to ensure it is selecting the correct files. Replace these actions with-printfirst.
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 coverfindin 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!