Cheat Sheet

find Command Examples

find walks a directory tree and matches files by name, type, size, age, owner, or permissions, then prints them or runs a command on them. This find command cheat sheet covers the tests and actions that come up in real work, with copy-paste examples.

Last updated September 5, 2026

Basic Syntax

. Tests combine left to right; the default action is . Always quote glob patterns so the shell does not expand them first.

CommandWhat it does
List everything under the current directory, recursively
Files named *.log under /var/log
Case-insensitive name match
Combine tests: files only, matching name
Search several trees at once
Hide Permission denied noise

Find by Name

CommandWhat it does
Exact name
Glob on the file name (basename only)
Ignore case
Glob against the whole path
Negate a test
Regex against the whole path, unlike -name
Saner regex dialect (GNU)

Find by Type

CommandWhat it does
Regular files
Directories
Symlinks
Files or symlinks ( is OR)
Empty files and directories
Empty directories only

Excluding Directories

CommandWhat it does
Filter results (still descends, simple)
Skip the directory entirely (fast)
Prune several at once
Or just do not go deep

With , keep the at the end or the pruned directories themselves show up in the output.

Find by Time

find counts age in whole 24-hour blocks: is "modified within 7 days", is "older than 7 days" (effectively 8 days and up), and is "exactly 7 days old", which is rarely what you want.

CommandWhat it does
Modified in the last 24 hours
Older than 30 days
Modified in the last hour
Untouched for more than 15 minutes
Modified more recently than ref.txt
Modified since a date
Modified today, counting from midnight (GNU)

Find by Size

Always give a unit: without one, the number means 512-byte blocks.

CommandWhat it does
Larger than 100 MB
Larger than 1 GB
Smaller than 10 KB
Between 1 and 5 MB
Zero-byte files

Running Commands with -exec

stands for the matched file. runs the command once per file; batches many files per run and is much faster.

CommandWhat it does
One command per file
Batched: one command, many files
Ask before each one
Search inside the matches
Run in each file's own directory
Feed the results to another pipeline

requires once, at the end. If the command needs the name twice (), use .

Deleting Files

Order matters: acts on everything matched so far, so it goes last. deletes everything under because the tests come too late.

CommandWhat it does
Dry run first: see exactly what will go
Then swap -print for -delete
Cleanup older than 30 days
Remove empty directories
Alternative with visible output

implies depth-first order and refuses non-empty directories, so it cannot take out a whole tree by accident the way can.

Pairing with xargs

and pass names separated by NUL bytes, so spaces and newlines in file names cannot break the pipeline.

CommandWhat it does
Content search over the matched set
Delete via xargs
Place each name mid-command
Four jobs in parallel
Count matches (fine without -print0)

covers most of what xargs does; xargs earns its keep for parallelism and mid-command substitution.

Permissions and Ownership

Modes pair naturally with the chmod cheat sheet and the chmod calculator.

CommandWhat it does
Mode is exactly 644
Owner-writable, whatever else is set
World-writable (audit)
All setuid binaries (audit)
Owned by alice
Group www-data
Orphaned files (deleted owner)
Fix stragglers

Depth and Filesystems

GNU find wants these before the other tests.

CommandWhat it does
This directory only, no recursion
Two levels down at most
Skip the starting directory itself
Stay on one filesystem (skip mounts)
Follow symlinks; this spelling finds broken ones

find vs locate vs fd

ToolWhen to use it
Live, exact, everywhere; all the tests on this page
Instant name lookup from an index; refreshes it (missing files = stale index)
Modern alternative: fast, regex by default, honours .gitignore, skips hidden dirs

Real Recipes

CommandWhat it does
20 biggest files on the disk
What changed in the last 24 hours
Log cleanup (dry-run with -print first)
Changed within a date range
Web dirs to 755 (then files to 644 with -type f)
Leftover editor and patch junk
Which subdirectory is eating the space

Gotchas

  • Unquoted patterns break silently: works until the shell expands the glob in the current directory first. Always quote: .
  • does not mean "older than yesterday": ages round down to whole days, so it matches 2 days and older.
  • Test order is left to right: put cheap, selective tests (, ) before expensive ones, and absolutely last.
  • macOS ships BSD find: and are missing, and it wants a path argument (, not ); gets GNU find as .
  • output is not safe for shell loops when names contain spaces; use or .
  • Searching includes /proc and network mounts; add or start from a narrower directory.

find Cheat Sheet FAQ

What is the difference between -mtime +7 and -mtime -7?
find measures age in whole 24-hour periods, rounding down. -mtime -7 matches files modified less than 7 days ago (recent files), -mtime +7 matches files whose age rounds to more than 7, which in practice means 8 days or older, and a bare -mtime 7 matches only the files that are exactly 7 whole days old, a much narrower set than people expect. So a cleanup like -mtime +30 keeps slightly more than 30 days of files, not fewer. When day granularity is too coarse, -mmin does the same thing in minutes: -mmin -60 is the last hour. For a precise cutoff date, use -newermt: -newermt 2026-09-01 matches files modified since that date.
What is the difference between -exec with \; and with +?
With \; find runs the command once per matched file: chmod 644 a, then chmod 644 b, and so on. With + it appends as many file names as fit onto one command line, like xargs: chmod 644 a b c. The + form is far faster for thousands of files because it starts a handful of processes instead of thousands. Use \; only when the command accepts a single file, or when you use {} more than once or not at the end, which + does not allow. The semicolon is escaped because it would otherwise end the shell command; + needs no escaping.
How do I find files containing a specific string in Linux?
That is grep's job, not find's: grep -rn "connection timeout" /var/log searches file contents recursively and prints matching lines with file and line number. Combine the two when you want content matching inside a name-filtered set: find . -name "*.py" -exec grep -n "TODO" {} + searches only Python files, and adding -l to grep prints just the file names. For trees with binary files or odd names, the safe pairing is find . -type f -print0 | xargs -0 grep -l "text". find alone only ever matches file metadata: name, size, age, type, permissions.
How do I exclude node_modules or .git from find?
The quick way is a filter: find . -type f -name "*.js" -not -path "*/node_modules/*" hides those results, but find still descends into every node_modules and wastes time in big trees. The fast way is -prune, which stops find from entering the directory at all: find . \( -name node_modules -o -name .git \) -prune -o -type f -name "*.js" -print. Read it as: if the name matches, prune (do not descend); otherwise apply your tests and -print. The explicit -print at the end matters, without it the pruned directories themselves appear in the output. For day-to-day source searching, fd does this by default by honouring .gitignore.
Is the find command recursive by default?
Yes. find . descends into every subdirectory with no flag needed, which is the opposite of ls and grep. You limit it rather than enable it: -maxdepth 1 searches only the directory itself, -maxdepth 2 goes one level further, and -mindepth 1 excludes the starting directory from the results, useful when acting on a directory's contents but not the directory. GNU find wants these depth options before tests like -name and warns otherwise. If a search is slow because it crosses into other filesystems like network mounts, -xdev keeps it on one filesystem.

Related cheat sheets