When you need to locate a file on a Linux system, find searches the filesystem itself—not the text inside files or a separate filename index. Give it a starting directory, add tests to narrow the results, and it will print matching paths.
find ./project -type f -name 'config.yaml'
This searches ./project and its subdirectories for regular files named config.yaml. The starting path matters: searching a focused directory is usually faster and easier to review than searching from /.
Build a search in three parts
A useful mental model is:
find starting-path tests actions
- Starting path controls where the search begins.
- Tests filter paths by name, type, size, age, and other attributes.
-
Actions determine what happens to matches. If you omit an action,
findprints them.
Start with a path and one test. Add filters only when you need them; this makes unexpected results easier to diagnose.
# Find a file in the current directory tree
find . -type f -name 'README.md'
# Search a specific system directory
find /etc -type f -name 'hosts'
# Search only the current directory, not nested directories
find . -maxdepth 1 -type f
-maxdepth is a GNU find option commonly available on Linux. If portability to other Unix-like systems matters, check the target system’s man find page.
Match names and file types
Use -name for a case-sensitive filename pattern and -iname when capitalization may vary. Patterns such as *.log should be quoted so the shell passes them to find instead of expanding them first.
# Find regular files ending in .log
find /var/log -type f -name '*.log'
# Match a name without regard to capitalization
find . -type f -iname 'readme.md'
# Find directories named cache
find . -type d -name 'cache'
# Find symbolic links
find . -type l
The common -type values are f for regular files, d for directories, and l for symbolic links. -name checks the basename; use -path if you need to match part of a path, such as a directory component:
find . -path '*/vendor/*' -type f
Filter by size or modification time
Size and age filters are useful for cleanup investigations, but their boundaries are easy to misread. In GNU find, -size +100M matches files whose size rounds to more than 100 MiB in the selected unit; it is not a byte-exact cutoff.
# Find files larger than 100 MiB
find . -type f -size +100M
# Find files modified within the last 24 hours
find . -type f -mtime -1
# Find files modified in the last 60 minutes
find . -type f -mmin -60
-mtime counts whole 24-hour periods, not calendar dates. With GNU find, -mtime +7 matches entries at least eight whole 24-hour periods old. Modification time also isn’t creation time. If your goal is to find which directories are using disk space, du is a better fit; see this guide to checking directory size with du.
Combine conditions without surprises
Adjacent tests are ANDed by default: a path must pass each test. Use -o for OR and parentheses to group alternatives. Escape the parentheses so the shell passes them to find.
# Regular .log files larger than 10 MiB
find . -type f -name '*.log' -size +10M
# Files ending in .jpg or .png
find . -type f \( -name '*.jpg' -o -name '*.png' \)
Grouping matters because AND binds more tightly than OR. When an expression mixes the two, parentheses make the intended logic explicit. Run the search without a modifying action first to see which paths match.
Run a command on matches
Use -exec to pass matching paths as arguments to another command. This avoids splitting filenames on spaces, which can happen with careless pipelines.
# Show details for each matching configuration file
find . -type f -name '*.conf' -exec ls -l -- {} \;
# Count lines, passing matches in batches
find . -type f -name '*.txt' -exec wc -l -- {} +
The \; form runs the command once per match; the + form passes multiple matches to each invocation where possible. The -- option tells commands that support it to treat following arguments as filenames, even if a filename begins with a hyphen.
find locates paths and checks filesystem metadata; it does not search file contents. To search inside selected files, combine it with a text-search tool. This example finds .conf files and searches their contents for listen:
find ./app -type f -name '*.conf' -exec grep -nH 'listen' -- {} +
For more ways to search file contents with grep, remember the distinction: find chooses files; grep looks for matching text in them.
Preview before deleting
GNU find supports -delete, but it removes matches immediately. First run the same search with -print and inspect every result. Keep the path and tests identical when you switch to deletion.
# Preview the exact candidates
find ./tmp -maxdepth 1 -type f -name '*.tmp' -print
# Run only after reviewing the preview
find ./tmp -maxdepth 1 -type f -name '*.tmp' -delete
Be especially cautious with broad starting paths, changing patterns, and commands that use variables you haven’t checked. A narrow search and a reviewable preview are safer than trying to recover from an accidental deletion.
When a search doesn’t behave as expected
If there are no results, check that the starting path exists, try -iname if capitalization may differ, and confirm that your -type, size, and time filters aren’t excluding the match. Quote wildcard patterns like '*.conf'.
If you see Permission denied, find may not be allowed to enter some directories. Narrow the search to paths you need and can access. Use elevated privileges only when a system-wide search is genuinely necessary; it can expose sensitive paths and produce a lot of output.
The reliable habit is simple: choose a focused starting path, add one filter at a time, and inspect matches before taking action. find is most useful when you treat searching and changing files as separate steps.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)