The Find Command: Complete Guide and Reference
Table of Contents
1. [Introduction](#introduction) 2. [Basic Syntax](#basic-syntax) 3. [Command Structure](#command-structure) 4. [Search Criteria Options](#search-criteria-options) 5. [Action Options](#action-options) 6. [Practical Examples](#practical-examples) 7. [Advanced Usage](#advanced-usage) 8. [Performance Considerations](#performance-considerations) 9. [Common Use Cases](#common-use-cases) 10. [Troubleshooting](#troubleshooting)
Introduction
The find command is one of the most powerful and versatile tools in Unix-like operating systems for searching files and directories. It allows users to locate files based on various criteria such as name, size, modification time, permissions, and many other attributes. Unlike simple file listing commands, find can recursively search through directory trees and perform actions on the files it discovers.
The find command is essential for system administrators, developers, and power users who need to locate specific files, perform bulk operations, or maintain file systems efficiently. It provides a comprehensive solution for file discovery and management tasks that would otherwise require complex scripting or manual searching.
Basic Syntax
The fundamental syntax of the find command follows this pattern:
`bash
find [path...] [expression]
`
Where:
- path specifies the starting directory or directories for the search
- expression defines the search criteria and actions to perform
Minimum Required Arguments
`bash
find /path/to/search
`
This basic form will list all files and directories recursively starting from the specified path.
Command Structure
The find command expression consists of several components that can be combined to create complex search queries:
| Component Type | Purpose | Example |
|----------------|---------|---------|
| Options | Control find behavior | -L, -H, -P |
| Tests | Define search criteria | -name, -size, -type |
| Actions | Specify operations on found files | -print, -delete, -exec |
| Operators | Combine multiple criteria | -and, -or, -not |
Global Options
| Option | Description | Usage |
|--------|-------------|-------|
| -P | Never follow symbolic links (default) | find -P /path |
| -L | Follow symbolic links | find -L /path |
| -H | Follow symbolic links on command line only | find -H /path |
| -D | Print diagnostic information | find -D exec /path |
Search Criteria Options
File Name and Path Criteria
| Test | Description | Example |
|------|-------------|---------|
| -name pattern | Match basename with pattern | find . -name "*.txt" |
| -iname pattern | Case-insensitive name match | find . -iname "*.TXT" |
| -path pattern | Match full path with pattern | find . -path "/temp/" |
| -ipath pattern | Case-insensitive path match | find . -ipath "/TEMP/" |
| -regex pattern | Match path with regular expression | find . -regex ".*\.log$" |
| -iregex pattern | Case-insensitive regex match | find . -iregex ".*\.LOG$" |
File Type Criteria
| Test | Description | File Type |
|------|-------------|-----------|
| -type f | Regular files | Standard files |
| -type d | Directories | Folder structures |
| -type l | Symbolic links | Link files |
| -type b | Block devices | Block special files |
| -type c | Character devices | Character special files |
| -type p | Named pipes (FIFOs) | Pipe files |
| -type s | Sockets | Socket files |
Size Criteria
| Test | Description | Example |
|------|-------------|---------|
| -size n[cwbkMG] | File size exactly n units | find . -size 100c |
| -size +n[cwbkMG] | File size greater than n units | find . -size +1M |
| -size -n[cwbkMG] | File size less than n units | find . -size -50k |
#### Size Units
| Unit | Description | Bytes |
|------|-------------|-------|
| c | Bytes | 1 |
| w | Words (2 bytes) | 2 |
| b | Blocks (512 bytes) | 512 |
| k | Kilobytes | 1024 |
| M | Megabytes | 1048576 |
| G | Gigabytes | 1073741824 |
Time-based Criteria
| Test | Description | Time Reference |
|------|-------------|----------------|
| -atime n | Access time exactly n days ago | Last accessed |
| -mtime n | Modification time exactly n days ago | Last modified |
| -ctime n | Change time exactly n days ago | Status changed |
| -amin n | Access time exactly n minutes ago | Last accessed |
| -mmin n | Modification time exactly n minutes ago | Last modified |
| -cmin n | Change time exactly n minutes ago | Status changed |
#### Time Modifiers
| Modifier | Description | Example |
|----------|-------------|---------|
| +n | More than n units ago | -mtime +7 (older than 7 days) |
| -n | Less than n units ago | -mtime -1 (within last day) |
| n | Exactly n units ago | -mtime 3 (exactly 3 days ago) |
Permission and Ownership Criteria
| Test | Description | Example |
|------|-------------|---------|
| -perm mode | Exact permission match | find . -perm 644 |
| -perm -mode | All specified bits set | find . -perm -644 |
| -perm /mode | Any specified bits set | find . -perm /644 |
| -user username | Owned by specific user | find . -user john |
| -group groupname | Owned by specific group | find . -group staff |
| -uid n | Owned by user ID n | find . -uid 1000 |
| -gid n | Owned by group ID n | find . -gid 100 |
| -nouser | No valid user owner | find . -nouser |
| -nogroup | No valid group owner | find . -nogroup |
Depth and Link Criteria
| Test | Description | Example |
|------|-------------|---------|
| -maxdepth n | Descend at most n directory levels | find . -maxdepth 2 |
| -mindepth n | Start at least n directory levels down | find . -mindepth 1 |
| -links n | File has exactly n hard links | find . -links 2 |
| -empty | File or directory is empty | find . -empty |
Action Options
Basic Actions
| Action | Description | Example |
|--------|-------------|---------|
| -print | Print full file path (default) | find . -name "*.txt" -print |
| -print0 | Print with null character separator | find . -name "*.txt" -print0 |
| -ls | Print file details in ls format | find . -name "*.txt" -ls |
| -delete | Delete found files | find . -name "*.tmp" -delete |
Execute Actions
| Action | Description | Example |
|--------|-------------|---------|
| -exec command {} \; | Execute command on each file | find . -name "*.txt" -exec cat {} \; |
| -exec command {} + | Execute command with multiple files | find . -name "*.txt" -exec grep "pattern" {} + |
| -execdir command {} \; | Execute command in file's directory | find . -name "*.txt" -execdir wc -l {} \; |
| -ok command {} \; | Interactive execute with confirmation | find . -name "*.tmp" -ok rm {} \; |
Practical Examples
Basic File Searches
#### Find files by name
`bash
Find all .txt files in current directory and subdirectories
find . -name "*.txt"Find files with exact name
find /home -name "config.conf"Case-insensitive search
find . -iname "readme*"`#### Find files by type
`bash
Find all directories
find /var -type dFind all symbolic links
find /usr/bin -type lFind all regular files
find . -type f`Size-based Searches
`bash
Find files larger than 100MB
find /var/log -size +100MFind files smaller than 1KB
find . -size -1kFind empty files
find /tmp -type f -emptyFind empty directories
find /tmp -type d -empty`Time-based Searches
`bash
Find files modified in last 24 hours
find . -mtime -1Find files modified more than 7 days ago
find /var/log -mtime +7Find files accessed in last 30 minutes
find . -amin -30Find files not accessed in last 30 days
find /home -atime +30`Permission and Ownership Searches
`bash
Find files with specific permissions
find . -perm 644Find files with write permission for group
find . -perm -020Find files owned by specific user
find /home -user johnFind files with no valid owner
find / -nouser 2>/dev/null`Complex Search Examples
#### Combining Multiple Criteria
`bash
Find .log files larger than 10MB modified in last week
find /var/log -name "*.log" -size +10M -mtime -7Find executable files owned by root
find /usr/bin -type f -user root -perm -111Find files with specific extension and permissions
find . -name "*.sh" -perm +111`#### Using Logical Operators
`bash
Find files that are either .txt or .doc
find . \( -name ".txt" -o -name ".doc" \)Find files that are NOT .tmp files
find . -not -name "*.tmp"Find large files that are not in system directories
find / -size +100M -not -path "/proc/" -not -path "/sys/" 2>/dev/null`Action Examples
#### Execute Commands on Found Files
`bash
Count lines in all .txt files
find . -name "*.txt" -exec wc -l {} \;Copy all .conf files to backup directory
find /etc -name "*.conf" -exec cp {} /backup/ \;Change permissions on all .sh files
find . -name "*.sh" -exec chmod +x {} \;Compress all .log files older than 30 days
find /var/log -name "*.log" -mtime +30 -exec gzip {} \;`#### Using exec with multiple files
`bash
Search for pattern in all .txt files (efficient)
find . -name "*.txt" -exec grep -l "pattern" {} +Remove all .tmp files (be careful!)
find /tmp -name "*.tmp" -exec rm {} +`Advanced Usage
Using Find with Pipes and Xargs
`bash
Find and process with xargs
find . -name "*.txt" -print0 | xargs -0 grep "pattern"Find and delete using xargs
find . -name "*.tmp" -print0 | xargs -0 rmFind and copy files
find . -name "*.conf" | xargs -I {} cp {} /backup/`Regular Expressions with Find
`bash
Find files matching regex pattern
find . -regex ".*\.\(jpg\|png\|gif\)$"Case-insensitive regex
find . -iregex ".*\.jpe?g$"Find files with numbers in name
find . -regex ".[0-9].\.txt$"`Find with Printf for Custom Output
`bash
Custom output format
find . -name "*.txt" -printf "%p %s %TY-%Tm-%Td\n"Show file permissions and size
find . -type f -printf "%M %10s %p\n"`Performance Optimization
#### Using Pruning to Skip Directories
`bash
Skip .git directories
find . -name ".git" -prune -o -name "*.txt" -printSkip multiple directory types
find . \( -name ".git" -o -name "node_modules" \) -prune -o -name "*.js" -printSkip system directories when searching root
find / \( -path "/proc" -o -path "/sys" -o -path "/dev" \) -prune -o -name "*.conf" -print 2>/dev/null`Common Use Cases
System Administration
#### Cleanup Operations
`bash
Find and remove temporary files older than 7 days
find /tmp -type f -mtime +7 -deleteFind large log files
find /var/log -name "*.log" -size +100M -lsFind core dump files
find / -name "core" -type f 2>/dev/null`#### Security Auditing
`bash
Find world-writable files
find / -perm -002 -type f 2>/dev/nullFind SUID files
find / -perm -4000 -type f 2>/dev/nullFind files with no owner
find / -nouser -o -nogroup 2>/dev/null`Development Tasks
#### Code Management
`bash
Find source code files
find . -name ".c" -o -name ".h" -o -name "*.cpp"Find files containing specific text
find . -name "*.py" -exec grep -l "import pandas" {} \;Count lines of code
find . -name "*.java" -exec wc -l {} + | tail -1`#### Build System Support
`bash
Find and remove build artifacts
find . -name ".o" -o -name ".a" -deleteFind configuration files
find . -name "Makefile" -o -name "*.mk"`Performance Considerations
Optimization Strategies
| Strategy | Description | Example |
|----------|-------------|---------|
| Use specific paths | Start search from most specific location | find /var/log vs find / |
| Limit depth | Use -maxdepth to reduce search scope | find . -maxdepth 2 |
| Use pruning | Skip unnecessary directories | find . -name ".git" -prune -o -print |
| Combine tests efficiently | Put most selective tests first | find . -name "*.txt" -size +1M |
Memory and I/O Considerations
`bash
For very large result sets, use -print0 with xargs
find /large/directory -name "*.txt" -print0 | xargs -0 process_fileUse exec with + for better performance
find . -name "*.txt" -exec grep "pattern" {} +Redirect errors to avoid cluttering output
find / -name "*.conf" 2>/dev/null`Troubleshooting
Common Issues and Solutions
| Issue | Cause | Solution |
|-------|--------|----------|
| Permission denied errors | Insufficient access to directories | Use 2>/dev/null or run with appropriate privileges |
| No output from find | Incorrect path or criteria | Verify path exists and criteria are correct |
| Find command too slow | Searching too broad a scope | Use -maxdepth, -prune, or more specific starting paths |
| Argument list too long | Too many files for exec | Use -print0 with xargs -0 |
Error Handling Examples
`bash
Suppress permission denied errors
find / -name "*.conf" 2>/dev/nullLog errors to file while showing results
find / -name "*.log" 2>errors.logContinue on errors
find . -name "*.txt" -exec process_file {} \; 2>/dev/null`Debugging Find Commands
`bash
Use -D to debug find execution
find -D exec . -name "*.txt" -exec echo {} \;Test with -print first before using -delete
find . -name "*.tmp" -printThen when satisfied:
find . -name "*.tmp" -deleteUse ls action to see file details
find . -name "*.txt" -ls`Advanced Pattern Matching
Glob Patterns
| Pattern | Description | Example |
|---------|-------------|---------|
| | Match any characters | find . -name ".txt" |
| ? | Match single character | find . -name "file?.txt" |
| [abc] | Match any character in brackets | find . -name "file[123].txt" |
| [a-z] | Match character range | find . -name "[a-z]*.txt" |
| [!abc] | Match any character not in brackets | find . -name "[!0-9]*.txt" |
Complex Pattern Examples
`bash
Find files with multiple extensions
find . -name ".jpg" -o -name ".png" -o -name "*.gif"Find files starting with specific prefix
find . -name "backup_*"Find files with specific pattern in middle
find . -name "_config_.xml"Find hidden files (starting with dot)
find . -name ".*" -type f`The find command is an incredibly powerful tool that becomes more useful as you combine its various options and criteria. Practice with different combinations to become proficient in locating exactly the files you need for any given task. Remember to always test destructive operations (like -delete) with -print first to ensure you are targeting the correct files.