find Command Cheat Sheet

Most used
find . -name '*.log'                       # by name (case-sensitive)
find / -iname 'nginx.conf' 2>/dev/null     # case-insensitive, hide permission errors
find . -type f -mtime -7                   # files changed in the last 7 days
find / -xdev -type f -size +1G             # files over 1 GiB on this filesystem
find . -type f -name '*.tmp' -delete       # delete matches (test without -delete first)
find . -type f -exec grep -l 'TODO' {} +   # run a command on the results

Syntax: find [starting-point...] [tests] [actions]. The starting point defaults to the current directory, and the default action is -print. Tests are combined with an implicit AND. This page covers GNU find from findutils, the version on all mainstream distros.

By name and path

CommandWhat it does
find . -name 'file.txt'Exact name, case-sensitive
find . -iname '*.jpg'Case-insensitive glob (.JPG, .jpg)
find . -path '*/cache/*'Match against the whole path, not just the name
find . -regex '.*\.\(jpg\|png\)'Regex on the whole path (Emacs syntax by default)
find . -regextype posix-extended -regex '.*\.(jpg|png)'Same with extended regex
find . -not -name '*.bak'Negate a test (! also works)
find . \( -name '*.c' -o -name '*.h' \)OR with grouping (escape the parentheses)
find . -maxdepth 1 -name '*.sh'Do not descend into subdirectories
find . -mindepth 2Skip the first levels
find . -name .git -prune -o -type f -printSkip a directory entirely
find / -xdev -name coreStay on one filesystem (skip /proc, /sys, other mounts)

By type, size and emptiness

CommandWhat it does
find . -type fRegular files only
find . -type dDirectories only
find . -type lSymbolic links
find . -xtype lBroken symlinks
find . -type f,dFiles or directories (GNU)
find . -size +100MLarger than 100 MiB (k, M, G suffixes)
find . -size -10kSmaller than 10 KiB
find . -size +100M -size -1GBetween 100 MiB and 1 GiB
find . -emptyEmpty files and empty directories
find . -type d -empty -deleteRemove empty directories

By time

-mtime counts in 24-hour periods, -mmin in minutes. -N means "less than N ago", +N "more than N ago".

CommandWhat it does
find . -mtime -1Content modified in the last 24 hours
find . -mtime +30Modified more than 30 days ago
find . -mmin -15Modified in the last 15 minutes
find . -atime +90Not accessed for 90 days (unreliable with noatime/relatime)
find . -ctime -1Metadata (permissions, owner) changed in the last day
find . -newer ref.txtModified more recently than a reference file
find . -newermt '2026-10-01'Modified after a date
find . -newermt '2026-10-01' ! -newermt '2026-10-08'Modified within a date range
find . -daystart -mtime 0Modified today (since midnight)

By owner and permissions

CommandWhat it does
find . -user aliceOwned by a user
find . -group www-dataOwned by a group
find / -nouser -o -nogroupFiles with no valid owner or group (left over from deleted users)
find . -perm 644Exactly mode 644
find . -perm -u+xAt least these bits set (user-executable)
find . -perm /o+wAny of these bits set (world-writable)
find / -xdev -perm -4000 -type fSUID binaries (security audit)
find . -readable / -writable / -executableFiles the current user can actually access

Permission numbers explained: Linux file permissions guide and the chmod calculator.

Actions

CommandWhat it does
find . -name '*.log' -printPrint paths (the default)
find . -name '*.log' -lsPrint in ls -dils format
find . -type f -printf '%s %p\n'Custom output: size and path (%TY-%Tm-%Td for date, %u owner, %m mode)
find . -print0NUL-separated output for xargs -0
find . -name '*.tmp' -deleteDelete matches (implies -depth)
find . -name '*.sh' -exec chmod +x {} +Run one command with many files at once
find . -name '*.sh' -exec chmod +x {} \;Run the command once per file
find . -name '*.conf' -ok rm {} \;Ask for confirmation before each command
find . -type d -execdir ...Run the command from the file's own directory (safer)
find . -name x -quitStop after the first match

Common recipes

Largest files on the system when you hit No space left on device (a full script is in find largest files):

sudo find / -xdev -type f -size +200M -printf '%s\t%p\n' 2>/dev/null | sort -rn | head -20 | numfmt --field=1 --to=iec

Delete log files older than 14 days, after checking what would be removed:

find /var/log/myapp -type f -name '*.log' -mtime +14 -print
find /var/log/myapp -type f -name '*.log' -mtime +14 -delete

Fix permissions on a web root: directories 755, files 644:

find /srv/www -type d -exec chmod 755 {} +
find /srv/www -type f -exec chmod 644 {} +

Search file contents only in certain files:

find . -type f -name '*.yaml' -exec grep -Hn 'image:' {} +

Handle names with spaces safely using xargs:

find . -type f -name '*.png' -print0 | xargs -0 -r optipng -o2

Archive files changed in the last week (see the tar cheat sheet):

find ~/projects -type f -mtime -7 -print0 | tar --null -T - -czf recent.tar.gz

Count files per extension:

find . -type f -name '*.*' | sed 's/.*\.//' | sort | uniq -c | sort -rn | head

Find and remove broken symlinks:

find /usr/local/bin -xtype l -print -delete

Gotchas

  • Quote the pattern. find . -name *.txt lets the shell expand *.txt first; if a matching file exists in the current directory you search for that exact name, or get "paths must precede expression". Write -name '*.txt'.
  • -exec ... {} + vs {} \;. + batches many paths into one command (fast, avoids Argument list too long) but {} must be the last argument before +. \; runs once per file and allows {} anywhere; escape or quote the semicolon so the shell doesn't eat it.
  • Order matters for -delete. find . -delete -name '*.tmp' deletes everything, because -delete runs before the name test. Put -delete last, and run the command with -print first.
  • -o needs parentheses. find . -name '*.c' -o -name '*.h' -exec rm {} + only applies -exec to .h files, because AND binds tighter than OR. Wrap the alternatives in \( ... \).
  • -size rounds up. -size -1M means "0 blocks of 1 MiB", which only matches empty files. Use -size -1024k.
  • -mtime +1 means at least 2 days. find drops the fractional part of the age, so "+1" is more than one full day, i.e. 48 hours or older.
  • Permission denied noise. Searching / as a normal user prints many errors; add 2>/dev/null or use sudo.

Reference: find(1). For searching inside files, see the grep cheat sheet.

Frequently asked questions

How do I find a file by name in Linux?

Use find / -name 'file.txt' 2>/dev/null, or -iname for a case-insensitive match. Quote patterns with wildcards: find . -name '*.log'.

What is the difference between -exec {} \; and -exec {} +?

\; runs the command once per file. + passes many files to one command invocation, which is much faster and avoids Argument list too long.

How do I find files modified in the last 24 hours?

find . -type f -mtime -1, or -mmin -60 for the last hour.

How do I find large files on Linux?

find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null lists files over 500 MB on the root filesystem.

Is find faster than locate?

No. locate (plocate on current distros) searches a prebuilt database and is nearly instant, but it can be out of date. find walks the disk every time and is always current.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.