DEV Community

dpm_bush
dpm_bush

Posted on Originally published at sshflow.com

A Practical Linux find Workflow: Locate, Filter, and Safely Act on Files

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

-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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

-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' \)
Enter fullscreen mode Exit fullscreen mode

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 -- {} +
Enter fullscreen mode Exit fullscreen mode

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' -- {} +
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)