05
Find & Locate
- Find large or recent files on full disk
- Locate binary/config by name
- Explain find vs locate
Must-know cold
find /path -name '*.log'·find /path -type f -mtime +7find /path -type f -size +100Mfind ... -print0 | xargs -0 -r ...(spaces-safe; GNU-rskips empty)which cmd/command -v cmd·type cmdlocateis a DB cache (fast, may be stale);findwalks the live tree
Commands
find
Definition: Walk a filesystem tree and select paths by name, type, time, size, and more.
| Option / test | Argument | Meaning | Example |
|---|---|---|---|
| (none) | PATH | Start path (always pass PATH) | find /var/log |
-name | PATTERN | Basename match (shell globs; quote it) | find . -name '*.conf' |
-iname | PATTERN | Case-insensitive -name | find . -iname 'readme*' |
-path | PATTERN | Full path match | find / -path '*/nginx/*.conf' |
-ipath | PATTERN | Case-insensitive path | |
-regex | REGEX | Whole path vs regex (GNU default = emacs, not ERE; -regextype) | find . -regex '.*\.py' |
-type | f / d / l / b / c / p / s | File, dir, symlink, block, char, pipe, socket | find . -type f |
-size | ±N[cwbkMG] | Size in rounded-up units (+100M = more than 100 MiB). -1k is only empty files, not “under 1k” — use -size -1024c | find / -type f -size +100M |
-mtime | ±N | Age in whole 24h periods, fraction dropped. +7 = at least 8 days ago; -1 = last 24h | find . -mtime +7 |
-mmin | ±N | Modified ±N minutes | find . -mmin -30 |
-atime / -amin | ±N | Access time (often stale: relatime / noatime mounts) | find . -atime +30 |
-ctime / -cmin | ±N | Metadata change time | |
-newermt | DATE | Modified more recently than DATE | find . -newermt '2026-08-01' |
-user | USER | Owned by USER | find /home -user alice |
-group | GROUP | Owned by GROUP | find /shared -group deploy |
-uid / -gid | N | Numeric ids | find / -uid 1000 |
-perm | MODE | Exact mode | find . -perm 644 |
-perm | -MODE | All listed bits set. -111 = u+g+o execute, not “any +x” | find . -perm -0002 (world-writable) |
-perm | /MODE | Any listed bit (GNU). Any +x is /111 | find . -perm /u=s setuid hunt |
-empty | — | Empty files/dirs | find . -type d -empty |
-maxdepth | N | Limit directory depth | find /var -maxdepth 2 -type d |
-mindepth | N | Start at depth N | find . -mindepth 1 |
-xdev | — | Don’t cross mount points | find / -xdev -name ... |
-mount | — | Same as -xdev (GNU) | |
-L | — | Follow symlinks | find -L . -type f |
-P | — | Never follow (default) | |
-writable | — | Writable by current user (GNU) | |
-executable | — | Executable/searchable (GNU) | |
-readable | — | Readable (GNU) | |
-inum | N | Inode number | Hardlink groups |
-links | N | Link count | |
-not / ! | test | Negate | find . ! -name '*.o' |
-a / -o | — | And (default) / Or. -o binds looser than -a — group with \(\) | find . \( -name a -o -name b \) -type f |
\( \) | — | Group tests | find . \( -name '*.c' -o -name '*.h' \) |
-print | — | Print path (default action) | |
-print0 | — | NUL-delimited print | Safe with xargs -0 |
-ls | — | ls -dils style listing | find . -name '*.log' -ls |
-printf | FORMAT | Custom print (GNU) | find . -printf '%p %s\n' |
-exec | CMD {} \; | Run CMD per file; {} = path | find . -name '*.tmp' -exec rm {} \; |
-exec | CMD {} + | Batch many paths into one CMD | Faster than \; |
-execdir | CMD {} \; | Run in file’s directory | |
-ok | CMD {} \; | Like -exec but prompt each | Safer delete |
-delete | — | Delete match (GNU). Implies -depth; cannot usefully pair with -prune | find . -name '*.tmp' -delete |
-quit | — | Stop after first match (GNU) | find / -name nginx -quit |
-prune | — | Don’t descend into match | Skip dirs |
Size units (-size)
| Suffix | Meaning |
|---|---|
c | bytes |
w | 2-byte words |
b | 512-byte blocks (default) |
k | KiB |
M | MiB |
G | GiB |
Flag combos
| Combo | Meaning | Example |
|---|---|---|
find /var -xdev -type f -size +100M | Large files on one FS | Disk full |
find /var/log -type f -mtime +14 | Logs older than 14 days | Cleanup candidates |
find . -name '*.log' -print0 | xargs -0 -r grep -l ERROR | Grep safely (-r = don’t run grep on empty GNU xargs) | Spaces in names |
find /home -type f -perm -0002 | World-writable files | Security audit |
find / -name 'nginx.conf' 2>/dev/null | Hide permission noise | |
find /path -mindepth 1 -maxdepth 1 -type d | Immediate subdirs only (-maxdepth 1 includes /path) | |
find . -type f -exec grep -l PAT {} + | Content search | vs recursive grep |
-exec punctuation:
{}is the path placeholder.\;ends “one invocation per file”.+ends “batch paths” (like xargs).
locate
Definition: Fast name search via a prebuilt database.
updatedbrebuilds it.
| Command | Argument | Meaning | Example |
|---|---|---|---|
locate | PATTERN | Search prebuilt DB for pathnames | locate nginx.conf |
locate -i | PATTERN | Case-insensitive | locate -i readme |
-n / -l | N PATTERN | Limit results (mlocate -n, plocate -l) | locate -n 20 nginx.conf |
locate -r | REGEX | Regex match | locate -r '/nginx\.conf$' |
locate -c | PATTERN | Count matches | locate -c '*.log' |
locate -e | PATTERN | Only existing files (recheck) | locate -e bin/ls |
updatedb | — | Rebuild database (usually root/cron) | sudo updatedb |
updatedb --prunepaths | paths | Skip paths when building | Config in /etc/updatedb.conf |
Flag combos
| Combo | Meaning | Example |
|---|---|---|
locate bin/nginx | Fast path guess | Then verify with ls |
sudo updatedb && locate foo | Fresh DB then search | After new installs |
Caveats: DB often ignores some paths; results can be stale; may not be installed (package mlocate / plocate).
which
Definition: Locate how the shell resolves a command name (PATH, alias, binary). Pair with
type,command -v, andwhereis.
| Command | Argument | Meaning | Example |
|---|---|---|---|
which | CMD | First PATH match (external) | which python3 |
which -a | CMD | All PATH matches | which -a java |
type | CMD | Shell resolution: alias/builtin/file | type ls |
type -a | CMD | All interpretations | type -a python |
command -v | CMD | Portable: how the shell would invoke it (path, alias, or function) | command -v nginx |
command -V | CMD | Verbose (bash) | command -V cd |
whereis | CMD | Binary, source, man guesses | whereis ls |
whereis -b | CMD | Binaries only | whereis -b ssh |
Flag combos
| Combo | Meaning | Example |
|---|---|---|
type cmd; command -v cmd | Alias vs real binary | Debug “wrong version” |
which -a java | Multiple JDKs on PATH | Toolchain hosts |
realpath
Definition: Resolve symlinks and print the canonical absolute path.
readlinkshows one hop.
| Command | Argument | Meaning | Example |
|---|---|---|---|
realpath | PATH | Absolute canonical path | realpath ./link |
readlink | LINK | Symlink target (one level) | readlink /usr/bin/python |
readlink -f | PATH | Canonicalize (GNU) | readlink -f ./x |
Common recipes
| Goal | Command |
|---|---|
| Config by name | find /etc -name '*.conf' 2>/dev/null | head |
| Large files | sudo find / -xdev -type f -size +200M 2>/dev/null |
| Recent deploys | find /opt/app -type f -mtime -1 |
| Empty dirs | find /tmp -type d -empty |
| Delete old temps | find /tmp -type f -mtime +7 -print then review → -delete |
| Safe xargs | find . -name '*.log' -print0 | xargs -0 -r ls -lh |
| Fast name search | locate nginx.conf |
| Where is binary | command -v nginx; type nginx |
| World-writable | find /opt -type f -perm -0002 2>/dev/null |
Pitfalls
- Always quote
-name '*.log'or the shell expands the glob too early. find /is slow and noisy — prefer a start path +-xdev.2>/dev/nullhides permission errors you may need.-type fdoes not include symlinks to files (-Pdefault).-Lfollows links and can loop;-type lis then almost never true.-perm -111is every execute bit, not “any +x” (/111).-sizerounds up to the unit.-size -1M/-1kmatch only empty files. Prefer-size -1048576cwhen you mean bytes.-mtime +7is more than 7 whole days (fraction dropped) ≈ ≥ 8×24h. Use-mminor-newermtfor precision.-atimelies onnoatime/relatimedisks.-maxdepth 1includes the start path. Immediate children:-mindepth 1 -maxdepth 1.-ois looser than implicit-a. Write\( -name a -o -name b \) -type f.-deleteimplies-depth(so-prunedoes nothing useful) and deletes everything the expression matches — put it last; preview with-print.- GNU
xargswithout-rstill runs the command once on empty input (grepthen reads stdin). Usexargs -0 -ror-exec … {} +. locate≠ live truth; new files wait forupdatedb. Flags differ (mlocate -nvsplocate -l).find+-exec \;is slow; prefer{} +.
For more details, try man <command> in your terminal.