Cheat Sheet

find Command in Linux

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 11, 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
Either name ( is OR)
Regex against the whole path, unlike -name
Saner regex dialect (GNU)
Hidden files, at any depth
Skip hidden files and directories entirely
Broken: the shell expands the glob before find sees it

The last row is the mistake everyone makes once. Unquoted, becomes whatever matches in the current directory, so gets a real file name (or an error about too many arguments) instead of a pattern. Quote it: .

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 .

Search File Contents

find only ever matches metadata. When the match has to be inside the file, that is grep; find's job is narrowing the set grep has to read.

CommandWhat it does
grep already recurses, so no find needed here
Content search inside a name-filtered set
Print only the names of files that match
Same, safe with spaces in names
Only search what changed today
List text files, skip binaries

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

Permission Denied Errors

Those messages go to stderr, so they never reach a pipe or a redirected results file. They only clutter the screen.

CommandWhat it does
Discard every error, including the real ones
Keep the errors, just not on screen
Skip unreadable files as a test (GNU)
Do not even descend into unreadable directories
Read everything, so there is nothing to hide
Narrow the search instead of silencing it

find still exits with status 1 after a permission error, so prints nothing even though the output looked fine.

Output Format and Sorting

is GNU only. On macOS use the or variants instead.

CommandWhat it does
Newest files first
A readable date next to each path
Biggest files first, in bytes
Base name only, no directory part
Sort by time without -printf (one batch)
Count the matches

Find Where a Command Lives

Looking for an executable is a different job. The shell already knows the answer, so asking find is the slow way round.

CommandWhat it does
Path the shell would actually run (POSIX, built in)
Every candidate: alias, function, and each binary on PATH
The familiar one, but blind to aliases and functions
Binary, source, and man page locations
Which Debian/Ubuntu package installed it
Same on RHEL, Fedora and friends
Last resort when it is not on PATH

find vs locate vs grep 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)
Matches file contents, not names; see the grep cheat sheet
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.
  • When says the disk is full but cannot account for the space, a deleted file is still held open by a process. That is an lsof job, not a find one.

find FAQ

Why does the find command say Permission denied, and how do I hide it?

Those lines come from directories your user cannot read, usually under /proc, /run, /root and other people's home directories. They go to stderr, not stdout, so they never contaminate a pipe or a file of results, only your screen. 2>/dev/null throws all of stderr away, including errors you would want to see, so 2>errors.txt is the safer habit when the search matters. GNU find also has -readable, a test that skips unreadable files instead of complaining about them. One thing no redirect changes: find still exits with status 1 after a permission error, so a chain like find ... && echo done stays silent even when the output looks clean.

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 over thousands of files because it starts a handful of processes instead of thousands. Use ; only when the command takes a single file, or when {} appears more than once or not at the end, which + does not allow. The semicolon is escaped because the shell would otherwise treat it as the end of the command. xargs is the third option and behaves like +, but it earns its place for -P parallelism and for -I{} when the file name has to sit in the middle of the command rather than at the end.

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 find where a command is located in Linux?

Not with find. The shell already knows, so ask it: command -v python3 prints the path it would run, type -a python3 lists every candidate including aliases and shell functions, and whereis python3 adds the source and man page. which is the familiar one but it is a separate program that knows nothing about your aliases or functions, which is why the same name can behave differently from what it reports. If a command you just installed is still not found, run hash -r to clear the shell's cached lookup table before blaming the package. Reach for find / -name only when the file is genuinely off PATH.

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