LibraryEditorial layoutCompact layout
Browse library

find

search Edit on GitHub

Walk directory trees and select files by name, type, size, age or permissions, then act on them.

Updated

find walks one or more starting paths and evaluates an expression for every entry. Tests filter, actions do something with the survivors; the default action is -print. Always give a starting path: BSD find requires one.

Match by name and type

Names and paths

TestMeaning
-name '*.md'Last path component matches a glob
-iname 'readme*'Same, ignoring case
-path '*/docs/*'Whole path matches a glob
find . -name '*.go' -not -name '*_test.go'

Quote globs so the shell does not expand them first.

Entry types

TestMeaning
-type fRegular file
-type dDirectory
-type lSymbolic link
-emptyEmpty file or directory

Limit depth

find . -maxdepth 1 -type d
find src -mindepth 2 -name '*.json'

Combine tests

find . \( -name '*.jpg' -o -name '*.png' \) -size +1M
find . -type f ! -perm -u=w

Tests are joined by an implicit AND; -o is OR and ! or -not negates. Escape parentheses for the shell.

Size, time and ownership

Size

TestMeaning
-size +100MLarger than 100 MiB
-size -10kSmaller than 10 KiB
-size 0Zero length

Modification time

TestMeaning
-mtime -7Modified less than 7 days ago
-mtime +30Modified more than 30 days ago
-mmin -15Modified within the last 15 minutes
-newer stamp.txtModified after stamp.txt

+n means more than, -n less than, plain n exactly n units.

Owner and permissions

find /srv -user deploy -type f
find . -type f -perm -o=w

-perm -mode matches when all listed bits are set.

Act on results

Run a command

find . -name '*.md' -exec wc -l {} +
find . -name '*.orig' -exec rm {} \;
find logs -type f -execdir gzip {} +

{} + passes many paths per call; {} \; runs once per file. -execdir runs from each file's directory.

Names with spaces

Tip

find . -type f -name '*.txt' -print0 | xargs -0 grep -l TODO

NUL separators survive spaces and newlines in file names. See grep for the -l option.

Delete matches

Warning

find build -name '*.tmp' -print     # preview first
find build -name '*.tmp' -delete

-delete is irreversible and acts the moment it is evaluated, so keep it last and preview with -print first.

Shape the walk

Skip a directory

find . -name .git -prune -o -type f -print

-prune stops descent into matching directories; the explicit -print keeps them out of the output.

Regular expressions

find -E . -regex '.*/v[0-9]+\.[0-9]+/.*'

-regex matches the whole path. -E selects extended syntax on BSD find; GNU find uses -regextype instead. See regex for syntax.