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, find prints 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.