find Command Explained
find searches the actual, live filesystem, and it can filter on far more than just a filename. Where locate trades some currency for speed, find trades some speed for complete accuracy and a genuinely deep set of filtering options.
Basic syntax
find /path/to/search -name "pattern"
find /var/log -name "*.log"
find . -name "config.yaml"
find /home -iname "readme*" # -iname: case-insensitive version of -name
Every find command starts with a path (where to search) followed by expressions describing what to match. -name matches filenames using shell-style wildcards, and requires exact case matching; -iname does the same thing but ignores case.
Filtering by modification time
find . -mtime -7 # modified within the last 7 days
find . -mtime +30 # modified more than 30 days ago
find . -mtime 7 # modified exactly 7 days ago (rarely useful precisely)
find . -mmin -60 # modified within the last 60 minutes
The - and + prefixes matter a great deal here: -7 means “less than 7,” +7 means “more than 7,” and no prefix means exactly 7. -mmin works identically but counts minutes instead of days, useful when you need much finer-grained recency than whole days allow.
Filtering by size
find . -size +100M # larger than 100 megabytes
find . -size -1k # smaller than 1 kilobyte
find . -size +0 # any non-empty file
find / -size +1G 2>/dev/null
# find every file over 1GB anywhere on the system, a common
# first step when trying to free up disk space
Size suffixes are c (bytes), k (kilobytes), M (megabytes), G (gigabytes). As with time filtering, + and - prefixes mean “larger than” and “smaller than” respectively.
Filtering by file type
find . -type f # regular files only
find . -type d # directories only
find . -type l # symbolic links only
This is commonly combined with other filters, for example finding only directories matching a name pattern, or only regular files above a certain size, since without -type a search matches files, directories, and links all together.
Combining multiple conditions
find /var/log -type f -name "*.log" -mtime -7 -size +10M
# regular files, ending in .log, modified in the last week,
# larger than 10 megabytes, all at once
Conditions listed together are implicitly combined with AND logic by default, meaning every condition must match. Explicit -or and parenthesized grouping (escaped for the shell) support more complex logic when needed:
find . \( -name "*.log" -or -name "*.tmp" \) -mtime +30
# files ending in EITHER .log or .tmp, older than 30 days
Running a command on every match: -exec
find . -name "*.tmp" -exec rm {} \;
# deletes every matching .tmp file, one rm invocation per file
find . -name "*.tmp" -exec rm {} +
# same result, but batches multiple matches into fewer rm
# invocations, which is generally faster for large result sets
{} is a placeholder that find substitutes with each matched filename. \; (escaped so the shell does not interpret it) terminates the command for -exec, running it once separately for every single match. The + terminator instead batches as many matched filenames as possible into fewer total command invocations, which is meaningfully faster when there are many matches, since starting a new process for every single file has real overhead.
# A very common real pattern: find and change permissions in bulk
find . -type f -name "*.sh" -exec chmod +x {} \;
# Find and grep the content of matching files
find . -name "*.py" -exec grep -l "TODO" {} \;
Using -delete directly
find . -name "*.tmp" -delete
-delete is a more direct built-in alternative to -exec rm {} \;, generally faster since it does not need to launch a separate rm process for every match at all.
A safe habit: preview before deleting
# Step 1: run the exact search WITHOUT any deletion action,
# and carefully review what it actually matches
find . -name "*.tmp" -mtime +30
# Step 2: only once confirmed, add the deletion action
find . -name "*.tmp" -mtime +30 -delete
Because find’s filtering can silently match far more (or less) than intended if a pattern, path, or time condition is slightly off, and because combining that with immediate deletion offers no chance to catch a mistake, always running the plain search first to review the exact list of matches is a cheap and worthwhile habit before ever attaching -delete or -exec rm.
Finding empty files and directories
find . -type f -empty # empty files
find . -type d -empty # empty directories
-empty is a quick, precise way to identify placeholder files or leftover empty directories that might be worth cleaning up, without needing to check sizes manually.
Frequently Asked Questions
What does the find command do?
find searches a directory tree in real time, checking the actual current state of the filesystem, and can filter results by name, size, modification date, file type, permissions, owner, and many other criteria, combinable in a single command. Unlike locate, its results always reflect the live filesystem at the moment it runs, at the cost of being slower on very large directory trees.
What is the basic syntax for a find command?
find starts with the path to search, followed by any number of filtering expressions, and optionally an action to take on each match. For example, find /var/log -name “*.log” -mtime -7 searches starting at /var/log, matching files ending in .log that were modified within the last 7 days.
How do I run a command on every file that find matches?
Use -exec followed by the command, with {} as a placeholder for each matched file, and ; to terminate the expression, such as find . -name “*.tmp” -exec rm {} ;, which deletes every matching .tmp file. A more efficient alternative for commands that accept multiple filenames at once is -exec command {} +, which batches multiple matches into fewer invocations of the command rather than running it once per file.
How do I search for files modified within a certain time range?
Use -mtime with a number of days: -mtime -7 means modified within the last 7 days, -mtime +30 means modified more than 30 days ago, and -mtime 7 means modified exactly 7 days ago. For more precise time ranges, -mmin works the same way but in minutes instead of days, useful for finding very recently changed files.
How do I search for files by size using find?
Use -size followed by a number and a unit suffix, such as -size +100M for files larger than 100 megabytes, -size -1k for files smaller than 1 kilobyte, or -size +0 for any non-empty file. Common suffixes are c (bytes), k (kilobytes), M (megabytes), and G (gigabytes).
Why should I be careful with find combined with -delete or -exec rm?
Because find’s filtering can match far more than you expect if a pattern or condition is even slightly off, and combining that with an immediate deletion action leaves no opportunity to review the list first. The safe pattern is to run the exact same find command without -delete or -exec first, to review the matched file list, and only add the deletion action once you have confirmed the results are exactly what you intended.