find Command in Linux: Syntax, Options & Practical Examples

GNU find walks a directory tree and matches files and folders by name, type, size, time, owner, and permissions. It can print paths, run commands on matches, or delete files — the standard tool for log cleanup, audits, and scripted file work on Linux.

Published

Updated

Read time 11 min read

Reviewed byDeepak Prasad

find Command in Linux: Syntax, Options & Practical Examples
About GNU find walks a directory tree and matches files and folders by name, type, size, time, owner, and permissions. It can print paths, run commands on matches, or delete files — the standard tool for log cleanup, audits, and scripted file work on Linux.
Tested on Ubuntu 25.04 (Plucky Puffin); find (GNU findutils) 4.10.0; kernel 7.0.0-27-generic
Package findutils
Man page find(1)
Privilege usually none; sudo for system-wide searches
Distros

GNU findutils on most Linux distros (Ubuntu, Debian, RHEL, Fedora, SUSE).

Fast name lookup from a database: locate.

find — quick reference

Starting points and depth

Control where the walk begins and how deep it recurses — useful on large trees like /var or /home.

When to use Command
Search from the current directory (default when no path is given) find .
Search from a specific directory find /var/log
Limit recursion to N levels below the start path find . -maxdepth 2
Skip the start directory itself; search from level N onward find . -mindepth 2
Stay on the same filesystem (do not cross mount points) find / -xdev -name "lost+found"

Name and path matching

Match basenames or full paths. Quote wildcard patterns so the shell does not expand them first.

When to use Command
Exact filename (case-sensitive) find . -name "readme.txt"
Filename match ignoring case find . -iname "readme.txt"
Files whose names match a shell-style pattern find . -name "*.log"
Match the full path string, not just the basename find . -path "./logs/*"
Skip a subdirectory entirely during the walk find . -path "./node_modules" -prune -o -print

File type, size, and emptiness

Filter by inode type, disk usage, or whether a file or directory has no content.

When to use Command
Regular files only find . -type f
Directories only find . -type d
Symbolic links only find . -type l
Files larger than 100 MB find . -type f -size +100M
Files smaller than 10 MB find . -type f -size -10M
Zero-byte regular files find . -type f -empty
Empty directories find . -type d -empty

Time-based tests

-mtime counts whole days since last content change; -mmin uses minutes for finer windows.

When to use Command
Modified within the last 7 days find . -mtime -7
Modified more than 30 days ago find . -mtime +30
Accessed within the last 24 hours find . -atime -1
Metadata changed within the last 3 days find . -ctime -3
Modified within the last 60 minutes find . -mmin -60

Ownership and permissions

Locate files by owner, group, or permission bits — common in security audits and cleanup scripts.

When to use Command
Files owned by a specific user find . -user "$(whoami)"
Files belonging to a specific group find . -group www-data
Exact permission mode (octal) find . -perm 755
At least these permission bits set (any of 644) find . -perm -644
Files with the setuid bit set find /usr/bin -perm -4000 2>/dev/null
Readable by the current user find . -readable

Actions on matches

Print paths by default; add actions to run commands, list details, or delete — preview matches before destructive actions.

When to use Command
Print matched paths (default action) find . -name "*.log" -print
Run a command once per match find . -name "*.log" -exec ls -lh {} \;
Run a command with many files batched ({} +) find . -name "*.log" -exec wc -l {} +
Delete matched files (irreversible — preview first) find . -name "*.tmp" -delete
Detailed ls-style listing of matches find . -name "*.conf" -ls
Stop searching after the first match find /etc -name "hosts" -quit

Help and version

When to use Command
Show brief usage find --help
Show findutils version find --version

find — command syntax

Synopsis from find --help on Ubuntu 25.04 (GNU findutils 4.10.0):

text
find [-H] [-L] [-P] [-Olevel] [-D debugopts] [path...] [expression]

Default path is the current directory; default expression is -print.
Expression may consist of: operators, options, tests, and actions.

If you omit the path, find starts in the current working directory. Tests and actions are evaluated in order; combine them with -and (implicit), -or, or -not. Filenames that start with a dash need care when passed to other tools — see dashed filenames in Linux.


find — command examples

Essential List everything under a directory

The simplest use is a recursive listing starting from . or an absolute path. Every file and directory under the start point is printed.

Run the command (lab tree under /tmp/find-lab-test):

bash
find /tmp/find-lab-test

Sample output:

text
/tmp/find-lab-test
/tmp/find-lab-test/bigfile.dat
/tmp/find-lab-test/link.txt
/tmp/find-lab-test/readme.txt
/tmp/find-lab-test/node_modules
/tmp/find-lab-test/scripts
/tmp/find-lab-test/scripts/run.sh
/tmp/find-lab-test/logs
/tmp/find-lab-test/logs/old.log
/tmp/find-lab-test/logs/app.log

Use -type f or -type d when you only want files or directories — the quick-reference tables above list those filters.

Essential Find files by name or extension

Use -name with a quoted pattern to match basenames. Wildcards * and ? are interpreted by find, not expanded by the shell.

Run the command:

bash
find /tmp/find-lab-test -name "*.log"

Sample output:

text
/tmp/find-lab-test/logs/old.log
/tmp/find-lab-test/logs/app.log

For a case-insensitive match, swap -name for -iname. Always quote patterns that contain * so the shell does not expand them in the current directory first.

Essential Regular files only — skip directories

-type f limits results to regular files. Pair it with other tests to avoid matching directory names.

Run the command:

bash
find /tmp/find-lab-test -type f

Sample output:

text
/tmp/find-lab-test/bigfile.dat
/tmp/find-lab-test/readme.txt
/tmp/find-lab-test/scripts/run.sh
/tmp/find-lab-test/logs/old.log
/tmp/find-lab-test/logs/app.log

Symlinks are not listed unless you use -type l or follow links with -L.

Common Find files larger than a size threshold

-size accepts c, k, M, G, and related suffixes. A leading + means strictly greater; - means strictly less.

Run the command:

bash
find /tmp/find-lab-test -type f -size +1M

Sample output:

text
/tmp/find-lab-test/bigfile.dat

Combine two -size tests to bracket a range, for example -size +50M -size -200M for files between 50 MB and 200 MB.

Common Files modified recently or long ago

-mtime -N matches files changed within the last N days; -mtime +N matches files older than N days.

Run the command:

bash
find /tmp/find-lab-test -mtime +30

Sample output:

text
/tmp/find-lab-test/logs/old.log

Use -mtime -7 for recent changes or -mmin -60 when you need a window measured in minutes instead of days.

Common Limit how deep find recurses

On large trees, -maxdepth keeps the walk shallow and faster. Depth 1 is the start directory itself; depth 2 includes its immediate children.

Run the command:

bash
find /tmp/find-lab-test -maxdepth 2 -type f

Sample output:

text
/tmp/find-lab-test/bigfile.dat
/tmp/find-lab-test/readme.txt
/tmp/find-lab-test/scripts/run.sh
/tmp/find-lab-test/logs/old.log
/tmp/find-lab-test/logs/app.log

Add -name "*.conf" or other tests after the depth limit to narrow results further.

Common Run a command on each match with -exec

-exec runs an external command for every match. {} is replaced by the path; \; ends the action for one file at a time.

Run the command:

bash
find /tmp/find-lab-test -name "*.log" -exec grep -H "error" {} \;

Sample output:

text
/tmp/find-lab-test/logs/app.log:error: disk full

For many files, -exec cmd {} + batches arguments into fewer process runs — often faster than \;.

Advanced Skip directories such as node_modules

-prune prevents descending into a path. Combine it with -o (OR) so other branches still print.

Run the command:

bash
find /tmp/find-lab-test \( -path "*/node_modules" -o -path "*/.git" \) -prune -o -type f -print

Sample output (note node_modules and .git are absent):

text
/tmp/find-lab-test/bigfile.dat
/tmp/find-lab-test/readme.txt
/tmp/find-lab-test/scripts/run.sh
/tmp/find-lab-test/logs/old.log
/tmp/find-lab-test/logs/app.log

Adjust the -path patterns to match directories you want to skip in your project tree.

Advanced Preview matches, then delete with -delete

-delete removes matched files immediately. Always run the same expression without -delete first to confirm the list.

Preview:

bash
find /tmp/find-lab-test -name "*.tmp"

Sample output:

text
/tmp/find-lab-test/empty.tmp

Delete after confirming:

bash
find /tmp/find-lab-test -name "*.tmp" -delete
find /tmp/find-lab-test -name "*.tmp"

Second command sample output (empty — file removed):

For production log rotation, combine age and name tests, for example find /var/log -name "*.log" -mtime +30 -delete, only after a dry run without -delete.

Advanced Permission denied on system paths

Searching / or /root as a normal user often prints Permission denied for directories you cannot read. The search continues, but stderr is noisy.

Run the command:

bash
find /root -maxdepth 1 2>&1 | head -3

Sample output:

text
/root
/root/golinuxcloud-static
/root/.gnupg
find: '/root/.gnupg': Permission denied

Redirect stderr to hide denials when you only care about readable paths:

bash
find /root -maxdepth 1 2>/dev/null

Use sudo find … when you genuinely need to inspect protected directories — not for everyday file searches.


find — when to use / when not

Use find when Use something else when
  • You need a live, accurate list of files matching size, time, owner, or permissions
  • You are cleaning logs, rotating backups, or auditing a specific directory tree
  • You want to run a command on each match (`-exec`, `-delete`)
  • The search criteria go beyond a simple name (empty files, SUID binaries, mtime windows)
  • You must exclude subtrees with `-prune` or stay on one filesystem with `-xdev`
  • You only know part of a filename and speed matters more than freshness → locate
  • You are searching inside file contents, not paths → grep or rg
  • You already have a list of paths and need to batch a command → xargs
  • You want a GUI or indexed desktop search → desktop file indexer, not terminal find

find vs locate

find locate
Data source Walks the filesystem in real time Queries a pre-built database (updatedb)
Accuracy Always current Can miss files until the next database update
Speed on large disks Slower — reads directories as it goes Very fast for simple name lookups
Filters Name, type, size, time, owner, permissions, actions Mainly path/name patterns
Best for Audits, cleanup scripts, complex criteria Quick “where is this file?” on a familiar host

See the locate command for database setup and updatedb.


Nearby tools for search, filtering, and batch processing.

Command One line
find Walk a tree and match by metadata (this page)
xargs Build command lines from stdin path lists
ls List one directory level

Browse the full index in our Linux commands reference.


find — interview corner

What does the find command do in Linux?

find (from GNU findutils) recursively walks directories starting from one or more paths. For each file system object it evaluates tests — name, type, size, modification time, owner, permissions — and optionally runs actions such as -print, -exec, or -delete.

Unlike locate, find reads the live directory structure, so results reflect the disk right now. That makes it the standard choice for log cleanup, security checks (SUID files), and automation.

A strong answer is:

"find walks a directory tree in real time, filters by tests like -name, -type, -size, and -mtime, and can print paths or run actions such as -exec and -delete. I use it when criteria are more than a simple filename or when the result must be current."

What does find -mtime -7 mean?

-mtime compares the file's last content modification time to now, in 24-hour day units.

  • -mtime -7 — modified less than 7 days ago (recent files)
  • -mtime +7 — modified more than 7 days ago (older files)
  • -mtime 7 — modified exactly around 7 days ago (rare in practice)

The minus sign means "less than N days"; the plus sign means "greater than N days". For minute-level windows use -mmin instead.

A strong answer is:

"find -mtime -7 matches files changed within the last seven days. Minus means newer than N days; plus means older than N days. For minutes I'd use -mmin."

When do you use find -exec versus find | xargs?

Both run a command on matched paths, but the wiring differs.

-exec cmd {} \; — one process per file; safe with odd filenames if {} is used correctly.

-exec cmd {} + — batches many paths into one command (like xargs).

find … -print0 | xargs -0 cmd — hands paths to xargs; use -print0 and xargs -0 when names may contain spaces or newlines.

Preview with find … alone before adding -delete or rm.

A strong answer is:

"I use -exec {} + for batching inside find, or find -print0 | xargs -0 when piping to another tool. For destructive actions I always preview the find expression first."

What is the difference between find and locate?
find locate
Mechanism Directory walk Database lookup
Freshness Real time Depends on updatedb schedule
Filters Rich (size, time, perm, …) Mostly path/name
Cost Higher I/O on big trees Low for simple queries

Use locate for a quick "is this file somewhere on the system?" Use find when age, size, or permissions matter, or when you must act on matches.

A strong answer is:

"locate is fast but can be stale; find is slower but live and supports rich filters and -exec. I pick find for cleanup scripts and audits, locate for quick name lookups."

Why must wildcard patterns be quoted in find -name?

The shell expands unquoted * before find runs. If you type:

bash
find . -name *.log

and the current directory has app.log, the shell may turn that into find . -name app.log — not what you intended.

Quoting keeps the pattern intact for find:

bash
find . -name "*.log"

Same rule applies to -path and -wholename patterns.

A strong answer is:

"I quote patterns like "*.log" so the shell doesn't glob them first — find should interpret the wildcards, not bash."


Troubleshooting

Symptom Likely cause Fix
Permission denied lines on stderr Normal user reading protected dirs 2>/dev/null, narrow the path, or sudo find … when appropriate
No matches but the file exists Wrong path, -maxdepth too shallow, or typo in -name Run find START -name 'exactname'; drop depth limits temporarily
-delete removed too much Expression matched more than expected Preview without -delete; add -type f and tighter -name / -mtime tests
Shell glob expanded the pattern Unquoted * in -name Quote the pattern: -name "*.log"
-exec runs once per file slowly Using \; on huge sets Switch to -exec cmd {} + or find … -print0 | xargs -0
Symlink surprises Default -P does not follow symlinks into dirs Use -L only when following links is intentional

References

Rohan Timalsina

is a technical writer and Linux enthusiast who writes practical guides on Linux commands and system administration. He focuses on simplifying complex topics through clear explanations.