Jul 18, 2022 6 min read

How to Use the find Command With exec

Table of Contents

The find command in Linux is an excellent tool to find files and directories based on given criteria.

You can take your findings to the next level by actually doing specific operations on the found files.

For example, you found all the files with .jpeg extension. How about renaming them with .jpg extension?

You cannot just pipe redirect the find command output to another command. It won't work that simply.

You have two ways to execute other commands on the result of the find command:

  • use xargs
  • use exec

There is already a detailed article on xargs command. This tutorial will focus on combining find and exec commands.

Using exec command with the output of file command

The basic syntax to execute find with exec is as follows:

find [path] [arguments] -exec [command] {} \;

Here's a quick explanation:

  • [command] is what you want to execute over results given by the find command.
  • {} is a placeholder that is used to hold results given by the find command.
  • \; says that for each found result, the [command] is executed. You need to escape the ; here and hence \;.
⚠️
There must be a space between {} and \;

There is another syntax that is slightly different from the above and is as follows:

find [path] [arguments] -exec [command] {} +

Here, + says for every result of the find command, the [command] is executed only once. All the results are passed to the [command] as arguments together. + does not need to be escaped with \+.

Still confused about the use of {} \; and {} +?

{} \; is like this (executing the commands for each found result):

ls file1.txt
ls file2.txt
ls file3.txt

{} + is like this (executing the command once with all results argument):

ls file1.txt file2.txt file3.txt

While it may seem like using {} + is the better option here, it's the opposite. If the find commands throw 50 results, you cannot pass them all as arguments together because there are restrictions on maximum command line length.

This is why you are better with {} \; unless you know exactly what you need.

Practical examples of combining find and exec commands

Let me share some common examples of find exec commands so that you can understand them better.

1. Find and display file attributes

In the first simple example of find exec command, I am going to display all the lock files that are under the /tmp directory and display their properties.

sudo find /tmp/ -type f -name *lock -exec ls -l {} \;

Here's the result:

[email protected]:~$ sudo find /tmp/ -type f -name *lock -exec ls -l {} \; 
-r--r--r-- 1 gdm gdm 11 Jul 17 08:01 /tmp/.X1024-lock
-r--r--r-- 1 gdm gdm 11 Jul 17 08:01 /tmp/.X1025-lock

2. Find and rename files

Yes, using find with exec you can rename files easily. The mv command is used for renaming the files. I'll be doing the same.

sudo find /home/sagar/Downloads/ -type f -name 'ubuntu*' -exec mv {} {}_renamed \;

The above command finds the files that start with the name ubuntu and store them inside the placeholder. Once the process of storing results inside the placeholder, it will add "_renamed" at the end of each file stored inside the placeholder.

Renaming files using find and mv

3. Collect and store file sizes

In this example, I will show you how you can collect the size of available files under a certain directory and create a file to save the given output.

I will collect each file's size under the /tmp directory and save the output under the /root directory with the filename of du_data.out

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

Now, let's have a look at what the recently created file under /root directory looks like.

An example of find exec command that collects the size of files and stores them

4. Remove files with specific parameters

Please be extra careful while automatically removing files. It could be catastrophic if you don't pay attention. Either use the interactive delete with rm -i or see the result of the find command first.

Another common example of the find exec command combination is to find files greater than a certain size and remove them. This works well if you are cleaning old logs.

I am removing files larger than 100 MB for demonstration under my Desktop directory.

find ~/Desktop -size +100M -exec rm {} \;

Similarly, you can also remove files based on how old they are. For example, let's remove files that are older than 10 days.

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

Here I used -mtime which identifies data modified in the last 24 hours and when paired +10 with it, it found and deleted files that are older than 10 days.

5. Execute specific tools

There are various cases where you may want to start certain tools or packages after finding the files.

For example, when I'm searching for any mp3 file, I want to run id3v2 which will bring details about found mp3 file.

find . -name "*.mp3" -exec id3v2 -l {} \;

id3v2 is the package that will show the details about the mp3 file and -l is used to show each mp3 tag associated with found mp3.

Using id3v2 to show music labels attached with mp3 file

6. Change the ownership of files and directories

Changing the ownership of files and directories is another example of how powerful the combination of find and exec is.

Here, I am looking for the files owned by the user named sagar and then change their ownership to milan.

sudo find /home/sagar/disk/Downloads -user sagar -type f -exec chown milan {} \;
Using find exec command to change file ownership

7. Changing the permission of files

So how about changing permissions of files using find and exec?

sudo find /home/sagar/disk/Downloads -type f -exec chmod 644 {} \;

In the above command, I used -type f so the command will only be applied to files under the given directory.

Changing read-write permissions of files

8. Collect md5sum for each file

In this example, I will demonstrate how you can collect md5sum for each available file under the /tmp directory.

sudo find /tmp/ -type f -exec md5sum {} \;

As you can see, the applied command collected md5sum for each available file with their names and md5sum.

Collecting md5sum for each file under /tmp

But what if you want to save this output and to certain directly with a different name? you just have to follow the given command and change names directly accordingly:

sudo find /tmp/ -type f -exec md5sum {} \; > /Documents/checksumdata.out

9. Combine exec with grep Command

The find command works on the file names. The grep command works on the contents of the files.

Combine the find and grep together with exec and you got yourself a powerful search tool in the Linux command line.

For example, the command below searches for all the files that have .hbs extension. With grep, it searches inside the content of those .hbs files for the string 'excerpt'.

find . -type f -name "*.hbs" -exec grep -iH excerpt {} \;

With the -H option, grep command will show the file names for each match. Here's the output:

[email protected]:~/Downloads/casper-hyvor$ find . -type f -name "*.hbs" -exec grep -iH excerpt {} \;
./author.hbs:                <div class="post-card-excerpt">{{bio}}</div>
./partials/post-card.hbs:            {{#if excerpt}}
./partials/post-card.hbs:                <div class="post-card-excerpt">{{excerpt}}</div>
./post.hbs:        {{#if custom_excerpt}}
./post.hbs:            <p class="article-excerpt">{{custom_excerpt}}</p>
./tag.hbs:                <div class="post-card-excerpt">

Bonus tip: Find with multiple exec commands

Yes, you can chain multiple exec commands with single find command.

Let me take the same example that you saw in the previous section and use two exec commands.

find . -type f -name "*.hbs" -exec echo {} \; -exec grep excerpt {} \;

It'll search for the .hbs files first and then echo their name with first exec command. And then, those files will be searched for the "excerpt" string.

The output will be slightly different than the one in the previous command:

[email protected]:~/Downloads/casper-hyvor$ find . -type f -name "*.hbs" -exec echo {} \; -exec grep excerpt {} \;
./index.hbs
./page.hbs
./default.hbs
./author.hbs
                <div class="post-card-excerpt">{{bio}}</div>
./error-404.hbs
./error.hbs
./partials/icons/twitter.hbs
./partials/icons/fire.hbs
./partials/icons/lock.hbs
./partials/icons/loader.hbs
./partials/icons/rss.hbs
./partials/icons/avatar.hbs
./partials/icons/facebook.hbs
./partials/post-card.hbs
            {{#if excerpt}}
                <div class="post-card-excerpt">{{excerpt}}</div>
./post.hbs
        {{#if custom_excerpt}}
            <p class="article-excerpt">{{custom_excerpt}}</p>
./tag.hbs
                <div class="post-card-excerpt">

Conclusion

Find is an already powerful command for searching files based on a number of criteria. The exec command gives you the ability to work on the result of the find command.

The examples I shared here are just a glimpse. Together, the find-exec command combination gives you endless possibilities for doing things in the Linux command line.  

Sagar Sharma
A software engineer who loves to tinker with hardware till it gets crashed. While reviving my crashed system, you can find me reading literature, manga, or watering my plants.

Join the conversation

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Linux Handbook.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.