The find command in Linux
find walks a directory tree and prints every path matching your criteria. Where grep searches inside files, find searches for the files themselves: by name, type, size, modification time, permissions and more. Combined with -exec, it can run a command on every result, which turns it into a bulk-operations tool.
How find works
find is a tree walker with a tiny expression language. It descends depth-first from each starting point, and for every path evaluates your predicates left to right — tests like -name and -mtime, joined by an implicit AND, with -o for OR and ! for NOT, short-circuiting exactly like a programming language.
Two consequences follow. First, order matters for performance and correctness: putting cheap, selective tests first prunes work, and actions like -delete apply at the point they appear in the expression — which is why -delete before the tests is the famous foot-gun. Second, the default action -print is only implied when you specify no action at all; add your own -exec and the implicit printing disappears. Understanding find as expressions, not options, is the moment it stops feeling arbitrary.
Syntax
find [PATH...] [CONDITIONS] [ACTIONS] Common options
| Option | What it does |
|---|---|
-name PATTERN | Match the file name (case-sensitive). Quote wildcards: -name "*.log". |
-iname PATTERN | Like -name but case-insensitive. |
-type f / -type d | Match only regular files (f) or directories (d). |
-size +10M | Files larger than 10 MB (use - for smaller, k/M/G units). |
-mtime -7 | Modified in the last 7 days (+7 means more than 7 days ago). |
-maxdepth N | Descend at most N directory levels. |
-exec CMD {} \; | Run a command on each result; {} is replaced by the path. |
-delete | Delete every match. Put it last, and test the find without it first. |
How to use find: examples
$ find . -name "*.txt" Every .txt file under the current directory, at any depth.
$ find /var/log -name "*.log" -type f Only regular files ending in .log under /var/log.
$ find . -type d -name "node_modules" Locate every node_modules directory in a project tree.
$ find . -size +100M Find files larger than 100 MB — the first step of any "what is filling my disk?" investigation.
$ find . -mtime -1 Everything modified in the last 24 hours.
$ find . -name "*.tmp" -delete Delete every .tmp file under the current directory. Run it without -delete first to see what would be removed.
$ find . -name "*.sh" -exec chmod +x {} \; Make every shell script executable: -exec runs chmod on each result.
Real-world use cases for find
Disk-space forensics
The disk filled overnight. find / -size +500M -mtime -2 2>/dev/null lists everything big and recent — nine times out of ten it's a runaway log or a core dump, identified in one command instead of an hour of clicking through directories.
Scheduled cleanup jobs
A nightly cron keeping /tmp civilized: find /tmp -type f -mtime +7 -delete. Every retention policy — old backups, stale sessions, rotated logs — compiles down to a find one-liner exactly like this.
Try find yourself
This is a live sandbox with a small filesystem (documents/, notes.txt,
backup.sh…). Nothing you do here can break anything — experiment freely.
Try: find . -name "*.txt"
Pro tips and common mistakes
- Always test destructive finds by running them WITHOUT -delete or -exec rm first: the printed list is your preview.
- -delete must come AFTER the conditions. find . -delete -name "*.tmp" deletes everything — the order is the trap.
- Silence permission noise when searching system-wide: append 2>/dev/null.
- find . -newer reference.txt lists files modified after a reference file — great for "what did that installer just change?".
- For -exec, {} + batches arguments (fast, like xargs) while {} \; runs once per file (needed when the command takes a single file).
Frequently asked questions about find
Why do I need quotes around the pattern in find -name?
Without quotes, the shell expands *.txt against the current directory before find ever runs, so find receives the wrong arguments. Quotes pass the pattern through intact.
What is the difference between find and locate?
find searches the real filesystem at the moment you run it; locate queries a prebuilt index, so it is much faster but can be out of date and needs the index installed.
How do I make find case-insensitive?
Use -iname instead of -name: find . -iname "readme*" matches README, ReadMe and readme.
Related commands
List the contents of a directory, with options for hidden files, long format, sorting and more.
rmDelete files and directories — and understand -r, -f and why there is no trash bin.
grepFind lines matching a pattern in files or piped input — the workhorse of text search.
chmodChange file permissions with numeric (755, 644) and symbolic (u+x) modes — clearly explained.