>_cmd.script

find

Search a directory tree for files matching criteria

Files

By CMD Script Team · 5 min read · Last updated

SYNTAX
find [PATH...] [EXPRESSION]

Options

Command options and flags
FlagDescription
-name PATTERNMatch files by name using shell glob syntax (case-sensitive); use -iname for case-insensitive
-type f|d|lRestrict matches to a type: f for regular files, d for directories, l for symlinks
-size +100MMatch by size; + for greater than, - for less than (suffixes: c, k, M, G)
-mtime -7Match by modification time in days; -7 means modified within the last 7 days, +7 means more than 7 days ago
-exec CMD {} \;Run CMD on each match, with {} replaced by the matched path; \; runs the command once per file
-exec CMD {} +Same as -exec but batches multiple matches into fewer command invocations, like xargs
-maxdepth NLimit recursion to N directory levels below the starting path
-deleteDelete matched files; must come after all filtering expressions

Distribution compatibility

  • Ubuntu
  • Debian
  • Fedora
  • Arch
  • macOS (BSD find, some flag syntax differs)

What it does

find searches a directory tree, starting from one or more given paths, for files and directories that match a set of criteria you specify: name, type, size, modification time, permissions, ownership, and more. Unlike tools that rely on a prebuilt database, find walks the actual filesystem every time it runs, so its results always reflect the current state of disk — at the cost of being slower than an indexed search for very large trees.

Beginner examples

  • find . — list every file and directory under the current directory
  • find /etc -name "*.conf" — find files ending in .conf under /etc
  • find . -iname "readme*" — case-insensitive name match
  • find . -type d — list only directories
  • find . -type f — list only regular files (no directories, symlinks, etc.)
find /home/user -name "*.jpg"

Advanced examples

  • Find files over 100MB anywhere on disk: find / -type f -size +100M
  • Find files modified in the last 7 days: find /var/log -mtime -7
  • Find files not modified in 30+ days and delete them: find /tmp -name "*.tmp" -mtime +30 -delete
  • Limit recursion depth to avoid descending too far: find . -maxdepth 2 -name "*.log"
  • Run a command on every match, one invocation per file: find . -name "*.sh" -exec chmod +x {} \;
  • Batch matches into fewer invocations (faster): find . -name "*.o" -exec rm {} +
  • Combine multiple conditions: find . -type f -name "*.py" -newer reference.txt
find / -type f -size +500M -exec ls -lh {} \; 2>/dev/null

Common mistakes

  • Forgetting that -exec CMD {} \; runs the command once per file, which is slow for thousands of matches — use -exec CMD {} + or pipe to xargs instead.
  • Putting -delete before other filters in the expression; find evaluates expressions left to right, so -delete must come last or it can delete more than intended.
  • Running find / without redirecting stderr, so the output is cluttered with "Permission denied" noise — add 2>/dev/null when searching system-wide as a non-root user.
  • Confusing -mtime -7 (modified less than 7 days ago) with -mtime +7 (modified more than 7 days ago) — the sign matters and is easy to get backwards.
  • Expecting find to be as fast as locate on huge filesystems; find does a live scan every time, while locate reads a prebuilt index.

Tips

  • Use -maxdepth to bound how deep find recurses when you only care about the top levels of a tree — this can dramatically speed up large searches.
  • Test destructive expressions (like -delete or -exec rm) by first running the same expression with -print (or no action) to see exactly what would be affected.
  • Combine -type f with -name to avoid matching directories that happen to share a name pattern.
  • Use find ... -print0 | xargs -0 ... when filenames might contain spaces or newlines, to avoid word-splitting bugs.

Best practices

  • Prefer find over locate when you need guaranteed up-to-date results, such as right after creating or deleting files.
  • Always dry-run destructive find expressions (drop -delete/-exec rm and just look at the match list) before making them destructive.
  • In scripts, use -print0/xargs -0 or -exec ... + rather than looping over unquoted find output, to handle unusual filenames safely.
  • Scope searches with a specific starting path and -maxdepth rather than searching / whenever you know roughly where the files live — it's faster and produces less noise.

Try it yourself

A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.

Real-world use cases

  • Locating and cleaning up old log files or temp files as part of a cron-driven cleanup script: find /var/log -name "*.log" -mtime +30 -delete.
  • Auditing disk usage by hunting down unexpectedly large files: find / -type f -size +1G.
  • Bulk-fixing permissions on a deployed codebase: find . -type f -name "*.sh" -exec chmod +x {} \;.
  • Finding files modified since a deployment to investigate what changed: find /app -newer /tmp/deploy-marker.

Common interview questions

  • How does find differ from locate? find performs a live filesystem walk every time it runs, so it's always accurate but potentially slow; locate looks up a prebuilt index (updatedb) that's fast but can be stale.
  • What's the difference between -exec CMD {} \; and -exec CMD {} +? The former invokes CMD once per matched file; the latter batches as many matches as possible into each invocation, similar to how xargs batches arguments, which is much more efficient for commands that support multiple file arguments.
  • How would you safely delete matched files? Build up the expression without -delete first, review the match list, and only then append -delete — or use -exec rm {} + after confirming the file list looks correct.
  • How do you avoid issues with filenames containing spaces when piping find output? Use find ... -print0 combined with xargs -0, which uses null bytes as separators instead of whitespace.

Frequently Asked Questions

What's the difference between find and locate?

find walks the filesystem live at the moment you run it, so results are always current but can be slow on large trees. locate queries a prebuilt index (updatedb) that's usually refreshed once a day, so it's much faster but can miss recently created or deleted files.

How do I find files larger than a certain size?

Use find /path -type f -size +100M to find regular files over 100 megabytes. Use - instead of + to find files smaller than a size.

How do I run a command on every file found?

Append -exec CMD {} \; to run CMD once per match, or -exec CMD {} + to batch matches into fewer invocations (faster for commands like grep or ls).

How do I delete files found by find?

Add -delete at the end of the expression, e.g. find /tmp -name '*.log' -mtime +30 -delete. Always test with -print (or no action) first to confirm the match set before deleting.

Cheat sheet

Download a quick-reference cheat sheet for find.