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.
Table of Contents
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 byfind.\;runscmdonce 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 byfind.\+runscmdonce 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:
rmwith-execdeletes matched files permanently, with no confirmation. Run thels -lversion first and verify the list before you switch torm.
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 -exec with hard links
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.



Cool. The examples are great. Thanks.
Enjoyed the examples. Quite often ‘… -exec rm …’ can be replaced with ‘… -delete’
Thanks.