Find Command Practice
find walks a directory tree and prints paths that pass an expression of tests and actions. This track drills -name, -type, -size, -mtime, and -exec so you filter the tree in one process instead of ls piped to grep. The same expressions show up in cleanup scripts and in -exec + batches that skip xargs.
Command Reference
size
| Command | Description |
|---|---|
find . -size -<num>M | Print paths whose size is less than the given number of megabytes. |
find . -size +<num>M | Print paths whose size is greater than the given number of megabytes. |
find . -size <num>M | Print paths whose size is exactly the given number of megabytes. |
find . -size +<num>M -size -<num>G | Print paths whose size is greater than N megabytes and less than N gigabytes. |
name
| Command | Description |
|---|---|
find <dir> -iname "<pattern>" | Match a basename under a start path, ignoring upper/lower case. |
find . -type f -name "<pattern>" | Print regular files whose basename matches the glob. |
find . -type d -name "<name>" | Print directories whose basename equals the given name. |
find . -name "<pattern>" | Print paths whose basename matches the glob, starting at the current directory. |
find . -name "<pattern>" -not -path "<path>" | Match a basename but skip paths that match a path glob (for example a vendor tree). |
find . -type f \( -name "<pat1>" -o -name "<pat2>" \) | Print regular files whose basename matches either of two globs. |
type
| Command | Description |
|---|---|
find . -type d | Print directories only, not regular files. |
find . -type f | Print regular files only, not directories or links. |
find . -type l | Print symbolic links only. |
find . -type d -empty | Print directories that contain no entries. |
find . -type f -empty | Print regular files that have zero size. |
owner
| Command | Description |
|---|---|
find . -group <name> | Print paths whose group owner matches the given group name. |
find . -user <name> | Print paths owned by the given user name. |
find . -user <name> -name "<name>" | Print paths owned by a user whose basename equals the given name. |
find <dir> -user <name> -iname "<pattern>" | Under a start path, print a user's files whose basename matches a case-insensitive glob. |
perm
| Command | Description |
|---|---|
find . -type f -perm 0777 | Print regular files whose mode is exactly rwx for user, group, and other. |
find . -type f ! -perm 777 | Print regular files whose mode is not exactly 777. |
find . -perm /u=s | Print paths that have the setuid bit set on the user class. |
find . -perm /g=s | Print paths that have the setgid bit set on the group class. |
find . -perm /a=x | Print paths executable by user, group, and other (any execute bit in the mask). |
time
| Command | Description |
|---|---|
find . -mtime -<num> | Print paths modified less than N days ago. |
find . -cmin -<num> | Print paths whose inode status changed in the last N minutes. |
find . -amin -<num> | Print paths last accessed in the last N minutes. |
find . -mtime +<num> | Print paths whose contents were last modified more than N days ago. |
find . -atime <num> | Print paths last accessed in the 24-hour window N days ago. |
find . -mmin -<num> | Print paths whose contents were modified in the last N minutes. |
filter
| Command | Description |
|---|---|
find . -maxdepth 1 -name "<name>" | Match a basename in the starting directory only — do not descend. |
find <dir1> <dir2> -name "<name>" -type f | Search two start directories for a regular file with the given basename. |
find . -path "<pattern>" | Match the relative path against a glob (directories in the path count). |
find . -regex "<pattern>" | Match the whole relative path against a regular expression, not just the basename. |
find . -mindepth <num> -maxdepth <num> -name "<name>" | Match a basename only between two descent depths (inclusive). |
action
| Command | Description |
|---|---|
find . -type f -name "<pattern>" -delete | Delete matching regular files in the tree (GNU find action, no extra process). |
find . -type f -name "<pattern>" -exec rm -f {} \; | Run rm once per matching regular file. |
find . -name "<pattern>" -exec mv {} <dir> \; | Move each matching path into a destination directory, one invocation per path. |
find . -name "<pattern>" -exec cp {} <dir> \; | Copy each matching path into a destination directory, one invocation per path. |
find . -name "<pattern>" -exec <cmd> {} \; | Run a command once for each matching path, substituting the path for {}. |
find . -name "<pattern>" -exec <cmd> {} \+ | Run a command with as many matching paths as fit in one invocation (xargs-style batch). |
Key Use Cases
- List every file matching a glob under a repo without a GUI search
- Restrict results to directories, regular files, or empty paths
- Find files larger than N megabytes before a cleanup
- Skip a vendor path while still matching a basename
- Delete matches, or run one command per path / per batch
- List files modified in the last hour
Frequently Asked Questions
What is the difference between -name and -path?
-name matches only the basename. -path matches the relative path, so */vendor/* excludes a directory prefix that -name cannot see.
When do I use -exec {} \; versus {} \+?
\; runs the command once per path. \+ batches paths into fewer invocations, like xargs. Wrong terminator is a different command in this track.
Does -maxdepth 1 search subdirectories?
No. Depth 1 is the starting directory only. Omit -maxdepth to walk the whole tree; combine -mindepth and -maxdepth to clamp a range.
Why not find | xargs grep, or use fd?
find tests metadata (type, size, mtime, perm) without opening file contents. grep -r searches bytes. fd is faster locally; this track is the portable find(1) expression you still need on a minimal host.
Ready to master Find commands?
Test your muscle memory with our spaced-repetition quiz system. Free forever.
