find: search for files
find walks through a directory tree and lists every file that matches your conditions: name, size, age, owner, type or permissions. It can also run a command on each file it finds.
Find by name
find . -name "*.log" # files ending in .log below the current directory
find /etc -name "nginx.conf"
find ~ -iname "*report*" # ignore case
find . -name "*.tmp" -o -name "*.bak" # either pattern (-o = or)
find . -path "*/cache/*" -name "*.json" # match the whole path
Always quote the pattern, or the shell expands *.log before find sees it.
Find by type
find /srv -type d # directories only
find /srv -type f # regular files only
find /usr/bin -type l # symbolic links
find . -type f -empty # empty files
Find by size
find / -xdev -type f -size +500M # larger than 500 MB, on the root file system only
find . -type f -size -10k # 9 KiB or smaller (sizes round up to whole units; -size -10240c for exact bytes)
find /var/log -type f -size +100M -exec ls -lh {} +
Units: c bytes, k kilobytes, M megabytes, G gigabytes. To see which directories use the most space, use du.
Find by time
find . -mtime -1 # modified in the last 24 hours
find /backup -mtime +30 # modified more than 30 days ago
find . -mmin -15 # modified in the last 15 minutes
find . -newer reference.txt # newer than another file
find /var/log -type f -newermt "2026-11-01" # modified since a date (GNU, BSD)
-mtime counts in whole days and drops any fraction: +30 means at least 31 full days ago, -1 means less than 24 hours ago. -atime and -ctime use access time and status-change time.
Find by owner and permissions
find /home -user anna # owned by anna
find / -xdev -nouser # owner UID has no user account (e.g. a deleted user)
find / -xdev -type f -perm -4000 # set-user-ID programs
find /srv -type f -perm -o+w # writable by everyone
find . -type f ! -perm 644 # not exactly 644
See file system security for what these checks mean.
Run a command on the results
find . -name "*.sh" -exec chmod +x {} + # many files per chmod call (fast)
find . -name "*.conf" -exec grep -l "Listen" {} + # which config files mention Listen
find . -type f -name "*.log" -exec gzip {} \; # one gzip per file
find . -name "*.jpg" -print0 | xargs -0 -P4 -n20 jpegoptim # in parallel with xargs
{} is replaced by the file name. End -exec with + to pass many names at once, or \; to run the command once per file. With xargs, always use -print0 and xargs -0 so names with spaces work.
Delete files safely
find /var/tmp/app -type f -mtime +14 -print # first look at the list
find /var/tmp/app -type f -mtime +14 -delete # then delete
-delete acts on everything that matches the conditions before it. find . -delete -name "*.tmp" deletes every file in the tree. Put -delete last, and test with -print first.
Limit where find looks
find / -xdev -name core # stay on one file system (skip /proc, network mounts)
find . -maxdepth 1 -type f # only the current directory, not subdirectories
find . -path ./node_modules -prune -o -name "*.js" -print # skip a directory
find / -name passwd 2>/dev/null # hide "Permission denied" messages
Combine conditions
Conditions next to each other must all match (and). Use -o for or, ! for not, and escaped parentheses for grouping:
find . -type f \( -name "*.jpg" -o -name "*.png" \) -size +1M
find . -type f ! -name "*.gz" -mtime +7
Faster alternatives
locate name(from theplocatepackage) searches a prebuilt index of all file names instantly. Update the index withsudo updatedb.fdis a fast, friendlier find for interactive use:fd '\.log$' /var.
The options shown work with GNU find on Linux and with BSD find on macOS, except where marked. Some commercial Unix versions lack some of them: AIX 7.3 find has no -delete, -maxdepth, -empty or -print0. Install GNU find there, or use -exec rm {} + and -prune.