10 Advanced Find Exec examples in Linux

Tired of manually digging through countless files and directories to find what you need? The find -exec command lets you locate files that match your criteria and act on them in one step—deleting, moving, changing permissions, searching contents, and more.

Give find a directory and a set of conditions to match, then hand the results to -exec to run a command on each one. Learn this pattern and you’ll save real time managing files at scale.

find -exec syntax

There are two forms of find -exec, and the difference matters.

Run the command once per result: \;

find /path [args] -exec [cmd] {} \;
  • {} is a placeholder for each result found by find.
  • \; runs cmd once for each result.
  • Effectively: cmd result1; cmd result2; ...; cmd resultN

Run the command once for all results: \+

find /path [args] -exec [cmd] {} \+
  • {} is a placeholder for the results found by find.
  • \+ runs cmd once with all results appended.
  • Effectively: cmd result1 result2 ... resultN

When to prefer \; over \+

Use \; (one run per file) when:

  • The tool doesn’t accept multiple files as arguments.
  • Running the tool on many files at once could use too much memory.
  • You want results to start appearing sooner, even if the full run takes longer.

Otherwise \+ is usually faster, because it launches far fewer processes.

find -exec with du — collect file sizes

Find all regular files under /tmp and print each one’s size:

find /tmp/ -type f -exec du -sh {} \;

Sample output:

4.0K    /tmp/dir1/config.cfg
1.2M    /tmp/dir2/archive.tar
8.0K    /tmp/notes.txt

-type f matches regular files. Redirect the output to save it to a file:

find /tmp/ -type f -exec du -sh {} \; > /root/du_database.out

find -exec with rm — remove old files

First list files older than 10 days under /tmp (always review before deleting):

find /tmp/ -type f -mtime +10 -exec ls -l {} \;

Then remove them:

See also: Mastering the Linux Command Line — Your Complete Free Training Guide

find /tmp/ -type f -mtime +10 -exec rm -f {} \;

-mtime +10 matches files whose data was last modified more than 10×24 hours ago. The /tmp/ directory tends to accumulate temporary files, so this is a common cleanup to reclaim disk space.

Caution: rm with -exec deletes matched files permanently, with no confirmation. Run the ls -l version first and verify the list before you switch to rm.

find -exec with mv — bulk rename

Rename matching files scattered across directories by appending _renamed:

find / -type f -name 'howtouselinux*' -exec mv {} {}_renamed \;

Here find locates files matching the pattern, and -exec runs mv on each so {} becomes both the source and the base of the new name.

find -exec with chmod/chown — chained commands

You can chain multiple -exec clauses on one line. Each subsequent -exec runs only if the previous one succeeded (returned exit status 0):

find /tmp/dir1/ -type f -exec chown root:root {} \; -exec chmod o+x {} \;

find -exec with grep — search file contents

To list the content matching a string across files:

find /tmp/ -type f -exec grep -i howtouselinux {} \;

Sample output:

This is a dummy config file owned by howtouselinux
This is a dummy config file owned by howtouselinux
This is a dummy config file owned by howtouselinux

Notice the filenames are missing. Because \; passes a single file to grep each time, grep has no reason to prefix the file name.

Printing the filename too

Switch to \+ so grep receives multiple files at once—now it prefixes each match with the file name:

find /tmp/ -type f -exec grep -i howtouselinux {} \+

Sample output:

/tmp/dir2/text3:This is a dummy config file owned by howtouselinux
/tmp/dir2/text1:This is a dummy config file owned by howtouselinux
/tmp/dir2/text5:This is a dummy config file owned by howtouselinux

Alternative approaches that also surface the file name:

find /tmp/ -type f -exec grep -i "howtouselinux" {} \; -exec echo {} \;
find /tmp/ -type f -exec grep -i "howtouselinux" {} \; -print

Tip: the cleanest option is grep‘s own -H flag, which always prints the file name—even for a single file. Use -l if you want only the names of matching files:

find /tmp/ -type f -exec grep -iH howtouselinux {} \;   # match lines, with names
find /tmp/ -type f -exec grep -il howtouselinux {} \;   # matching file names only

find -exec with a shell command

Run a shell to do more than a single command allows:

find ./ -type f -exec bash -c 'ls -lrt "$1"' _ {} \;

Passing {} as a positional argument ("$1") rather than embedding it inside the script string is safer—it avoids quoting problems with unusual file names.

find -exec with a pipe

Because a plain -exec can’t contain a pipe, wrap the pipeline in sh -c:

find /tmp/dir1/ -type f -exec sh -c 'grep -Ei a "$1" | grep -i howtouselinux' sh {} \;

This is shell programming: the sh {} at the end passes the found file into the script as $1. The same positional-argument pattern in isolation:

sh -c 'echo "You gave me $1, thanks!"' sh "apples"

Output:

You gave me apples, thanks!

So the pipeline above effectively runs, for each file:

grep -Ei a filename | grep -i howtouselinux

find -exec with grep and sed

Combine find -exec with sed (or awk) to transform the output. Here we match lines, echo the file name, then rewrite howtouselinux to deep:

find /tmp/dir1/ -type f -exec grep howtouselinux {} \; -exec echo {} \; | sed 's/howtouselinux/deep/g'

Find regular files that have more than one hard link:

find /tmp/dir1/ -links +1 -type f -exec echo {} \;

-links +1 matches files whose hard-link count is greater than one.

Avatar photo
David Cao

David is a Cloud & DevOps Enthusiast. He has years of experience as a Linux engineer. He had working experience in AMD, EMC. He likes Linux, Python, bash, and more. He is a technical blogger and a Software Engineer. He enjoys sharing his learning and contributing to open-source.

Articles: 275

3 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *