find, locate, and xargs
Concepts
find — Search for Files by Criteria
find walks the directory tree and tests each file against your criteria. It is powerful, flexible, and available everywhere.
find [starting-path] [tests] [actions]
Search by Name
# Find by exact name
find /etc -name "hosts"
# Case-insensitive
find /home -iname "readme*"
# Wildcards (must be quoted to prevent shell expansion)
find . -name "*.log"
find . -name "*.txt" -o -name "*.md" # -o = OR
Search by Type
find /var -type f # regular files
find /var -type d # directories
find /var -type l # symbolic links
Search by Size
find /var/log -size +10M # larger than 10 MB
find . -size -1k # smaller than 1 KB
find . -size +100M -size -1G # between 100 MB and 1 GB
# Units: c=bytes, k=KB, M=MB, G=GB
Search by Time
# Modified time (days)
find /tmp -mtime -1 # modified in the last 24 hours
find /tmp -mtime +30 # modified more than 30 days ago
# Accessed time
find . -atime -7 # accessed in the last 7 days
# Modified time (minutes)
find . -mmin -60 # modified in the last 60 minutes
# Newer than a file
find . -newer reference.txt
Search by Permissions and Ownership
# Exact permission
find /usr -perm 755
# At least these permissions set
find . -perm -644
# Owned by user
find / -user kmiguel 2>/dev/null
# Owned by group
find / -group www-data 2>/dev/null
# Files with no owner (orphaned)
find / -nouser 2>/dev/null
Search by Depth
find . -maxdepth 1 -name "*.txt" # current directory only
find . -maxdepth 2 -type d # at most 2 levels deep
find . -mindepth 2 -name "*.conf" # skip the first level
Combining Tests
# AND (default) — both must be true
find . -name "*.log" -size +1M
# OR
find . -name "*.jpg" -o -name "*.png"
# NOT
find . ! -name "*.tmp"
find . -not -user root
# Grouping with parentheses (must be escaped)
find . \( -name "*.log" -o -name "*.tmp" \) -mtime +30
Actions
# Default action: -print (show the path)
find . -name "*.txt"
# Delete matching files
find /tmp -name "*.tmp" -delete
# Execute a command on each result
find . -name "*.log" -exec ls -lh {} \;
# {} is replaced by the filename. \; ends the command.
# Execute with confirmation
find . -name "*.bak" -ok rm {} \;
# More efficient: pass multiple files at once (like xargs)
find . -name "*.txt" -exec grep -l "TODO" {} +
# {} + passes as many files as possible in one command invocation
locate — Fast Filename Search
locate searches a pre-built database, making it much faster than find — but the database may be stale.