The Linux find Command: A Practical Guide with Examples
— ny_wk

The Linux find command is one of those tools that feels cryptic until it suddenly becomes indispensable. Need every log older than 30 days? Every file over 1 GB? Every .tmp deleted in one shot? find does it all. Here's a practical, example-driven guide that takes you from the basic syntax to the patterns you'll actually use every week.
The basic syntax
find [path] [conditions] [actions]
You give it where to look, what to match, and optionally what to do with the matches. With no action, it just prints the paths. Example — every file under the current directory:
find . -type f
Find by name
find . -name "*.log"— files ending in .log (case-sensitive).find . -iname "readme*"— case-insensitive match.find /etc -name "*.conf"— search a specific path.
Quote the pattern ("*.log") so the shell passes the wildcard to find instead of expanding it first.
Find by type, size, and time
| Goal | Command |
|---|---|
| Only directories | find . -type d |
| Only files | find . -type f |
| Bigger than 100 MB | find . -size +100M |
| Smaller than 1 KB | find . -size -1k |
| Modified in last 7 days | find . -mtime -7 |
| Older than 30 days | find . -mtime +30 |
| Accessed in last 60 minutes | find . -amin -60 |
For time: -mtime counts in days, -mmin in minutes; +N means "more than N ago," -N means "less than N ago."
Find by permissions and owner
find . -perm 0777— files with exactly those permissions.find . -perm -u+s— files with the setuid bit (a security audit favorite).find /home -user alice— files owned by a user.find . -empty— empty files or directories.
Do something with the results: -exec and xargs
This is where find becomes powerful. Run a command on each match:
find . -name "*.tmp" -exec rm {} \; — delete each .tmp ({} is the match, \; ends the command).
Faster for many files, batch them with +:
find . -name "*.log" -exec gzip {} +
Or pipe to xargs (use -print0/-0 to handle spaces safely):
find . -name "*.bak" -print0 | xargs -0 rm
Combine conditions
- AND is implicit:
find . -type f -name "*.sh"(files AND named *.sh). - OR:
find . -name "*.jpg" -o -name "*.png". - NOT:
find . -type f ! -name "*.txt". - Limit depth:
find . -maxdepth 1 -type f(current dir only, no recursion).
Real-world one-liners
- Clean logs older than 14 days:
find /var/log -name "*.log" -mtime +14 -delete - Find the biggest files:
find . -type f -size +500M -exec ls -lh {} + - Fix directory permissions only:
find . -type d -exec chmod 755 {} + - Find files modified since a reference file:
find . -newer /tmp/marker
Common pitfalls
- Unquoted wildcards —
find . -name *.logcan break; always quote:"*.log". - Spaces in filenames — pipe with
-print0 | xargs -0, not plainxargs. - -delete is irreversible — run the
findwithout-deletefirst to preview matches. - -mtime confusion —
-mtime +7means more than 7 days ago, not "in the next 7 days." - Permission-denied noise — add
2>/dev/nullto hide errors when searching system paths as a non-root user.
Key takeaways
find [path] [conditions] [actions]— where, what, and what-to-do.- Match by name (
-name/-iname), type, size, time (-mtime/-mmin), perms/owner. - -exec (with
\;or+) orxargs -0runs commands on matches. - Always preview before
-delete, and quote wildcards.
Frequently asked questions
What's the difference between -exec ; and -exec +?
\; runs the command once per file; + batches many files into one command (much faster for large sets).
How do I find files modified in the last hour?
find . -mmin -60 — -mmin is minutes, -60 means within the last 60.
Why does find spew "Permission denied"?
You're searching paths you can't read. Append 2>/dev/null to suppress those errors, or run with sudo if appropriate.
find vs locate — which is faster?
locate queries a prebuilt database (instant but can be stale); find scans live (always accurate, slower). Use locate for quick name lookups, find for precise, real-time queries with conditions/actions.
Learn the condition flags and -exec, keep the pitfalls in mind, and find becomes the Swiss-army knife you reach for whenever "where is that file / clean these up" comes up.