Search for Files with the find Command in Linux
Learn how to use Linux find to recursively search for files and directories by name, type, size, ownership, permissions, and combined conditions.
The find command searches a Linux filesystem by recursively walking a directory tree and testing each path it encounters. It is useful when you need to locate files or directories by name, type, size, owner, group, or permissions.
Unlike locate, which normally searches a prebuilt database, find examines the current filesystem directly. This makes its results current, but a broad find search is often slower than a database lookup.
Basic find Command Structure
The general form is:
find PATH EXPRESSION
PATH is the starting location for the search. An expression contains tests, operators, and optionally actions that determine which paths match.
.means the current directory./homemeans the/homedirectory./means the filesystem root, so the search can traverse the entire visible filesystem.
For example:
find . -name "notes.txt"
This starts in the current directory, descends into its subdirectories, and prints paths whose names match notes.txt.
Search by Name
Use -name to match a filename pattern. Matching is case-sensitive, and the test applies to the final name component rather than the complete path.
find . -name "so*"
The wildcard * matches any sequence of characters, including an empty sequence. This command can return files and directories whose names begin with so.
Other useful patterns include:
find . -name "*.log
echo"
find . -name "backup*"
find . -name "report-2026-*.txt"
The first example above is intentionally shown as a pattern illustration; use one command at a time, such as:
find . -name "*.log"
find . -name "backup*"
find . -name "report-2026-*.txt"
Quote wildcard patterns. Without quotes, the shell may expand * against names in the current directory before find receives the pattern.
Use -iname for case-insensitive matching:
find . -iname "readme*"
This can match names such as README, Readme.txt, and readme.md.
Search by File or Directory Type
A name test alone can match any path type. Add -type when you want to restrict the result:
-type fmatches regular files.-type dmatches directories.
find . -type f -name "so*"
find . -type d -name "so*"
The first command finds only regular files beginning with so; the second finds only directories with those names.
Common find Expressions
| Expression | Purpose | Example |
|---|---|---|
-name | Case-sensitive filename pattern | -name "*.conf" |
-iname | Case-insensitive filename pattern | -iname "readme*" |
-type f | Regular files only | -type f |
-type d | Directories only | -type d |
-size | Filter by file size | -size +10M |
-user | Filter by owning username or UID | -user alice |
-group | Filter by owning group | -group developers |
-perm | Filter by permission bits | -perm 775 |
Search by File Size
Use -size followed by a number and an optional unit. A comparison prefix changes whether the size must be larger or smaller.
find . -type f -size +300c
find /var/log -type f -size +10M
The first command finds regular files larger than 300 bytes. The second searches for regular files larger than 10 MiB under /var/log.
| Syntax element | Meaning | Example |
|---|---|---|
c | Bytes | -size +300c |
k | Kibibytes, based on 1024 bytes | -size +500k |
M | Mebibytes, based on 1024 kibibytes | -size +10M |
G | Gibibytes, based on 1024 mebibytes | -size +1G |
+ | Greater than the stated size | -size +1M |
- | Less than the stated size | -size -1M |
| No prefix | Exact size unit value | -size 1M |
In GNU find, size values are handled in units and rounded up to whole units for comparison. Therefore, use c for precise byte-oriented searches, and use + or - when you mean a range rather than an exact size.
Search by Ownership
A Linux file has an owning user and an owning group. Use -user to search by username or numeric UID, and -group to search by group name or group identifier.
find /home -type f -user alice
find . -type f -user 1001
find /srv -group developers
Replace alice and developers with accounts and groups that exist on your system. A UID is the numeric identifier associated with a Linux user account.
Searching a broad path may produce permission errors because your account cannot traverse every directory. Search locations you are allowed to inspect, or use elevated privileges only when there is a clear administrative reason.
Search by Permissions
A Linux permission mode is a numeric representation of read, write, and execute permissions for the owner, group, and others. For example, 775 commonly means:
- Owner: read, write, execute
- Group: read, write, execute
- Others: read and execute
Use -perm to test permission bits:
find . -perm 775
With a bare numeric mode, this searches for an exact mode match. That means the relevant permission bits must correspond exactly to 775.
GNU find also supports forms for testing selected bits:
-perm -775matches paths where all bits represented by775are set. Other bits may also be set.-perm /775matches paths where at least one bit represented by775is set.
Choose the form based on the requirement. An exact mode search can miss a file that has the desired bits plus additional permissions.
Combine Search Conditions
Consecutive tests use implicit AND by default. Every test must match:
find . -name "t*" -perm 775
This returns paths whose names begin with t and whose exact permission mode is 775.
You can write the AND operator explicitly with -and:
find . -type f -and -name "*.conf"
Use -or when either condition may match. Escape parentheses so the shell passes them to find instead of interpreting them:
find . \( -name "*.txt" -o -name "*.log" \)
This finds paths ending in either .txt or .log. Parentheses are especially important when combining alternatives with additional conditions:
find . -type f \( -name "*.txt" -o -name "*.log" \) -size +1M
Here, the path must be a regular file, must have either extension, and must be larger than 1 MiB.
Interpreting Results Safely
When no action is specified, find prints matching paths by default. Results are usually one path per line:
find . -type f -name "*.sh"
Begin with a narrow path and a non-destructive query. Searching from / can take a long time, produce a large result set, and encounter directories you cannot read.
- Start with
., a home directory, or a specific project directory. - Add
-type for-type dto avoid irrelevant object types. - Review output before using actions that modify files.
- Do not add deletion or execution actions until the search criteria are verified.
Troubleshooting find Searches
Wildcard results are unexpected
The shell may have expanded an unquoted * before find ran. Quote the pattern:
find . -name "*.log"
Directories appear in a file search
A name test matches both files and directories. Add -type f:
find . -type f -name "report*"
Capitalization prevents a match
-name is case-sensitive. Use -iname when capitalization should not matter:
find . -iname "*.jpg"
Permission denied messages appear
Your account may not be able to traverse every directory below the selected path. Search a permitted directory, adjust access when authorized, or use elevated privileges only when justified.
A size query returns unexpected results
Check the unit and comparison prefix. Use c for bytes, k for kibibytes, M for mebibytes, and G for gibibytes. Add + for larger than or - for smaller than.
A permission search misses apparently suitable files
You may have used an exact mode when you meant to test selected bits. Compare -perm 775 with -perm -775, and decide whether extra permission bits should be allowed.
Exam-Relevant Notes
findrecursively walks a directory tree from the path you provide..means the current directory, while/means the filesystem root.- Quote wildcard patterns such as
"*.log". -nameis case-sensitive;-inameis case-insensitive.-type fselects regular files, and-type dselects directories.- Multiple tests are joined with implicit AND unless you use operators such as
-or. - Escape grouping parentheses as
\(and\). - A bare
-permmode is an exact match; prefixed forms test permission bits differently. findsearches the live filesystem, whilelocategenerally searches an index that may not reflect recent changes.