17.10 Running Commands on What You Find
[Often, when you find a file, you don't just want to see its name; you want to do something, like grep for a text string. To do this, use the -exec operator. This allows you to specify a command that is executed upon each file that is found. -TOR ]
The syntax is peculiar and in many cases, it is simpler just to pipe the output of find to xargs (17.2 ) . However, there are cases where -exec is just the thing, so let's plunge in and explain its peculiarities.
The -exec operator allows you to execute any command, including another find command. If you consider that for a moment, you realize that find needs some way to distinguish the command it's executing from its own arguments. The obvious choice is to use the same end-of-command character as the shell (i.e., the semicolon). Since the shell uses the semicolon (8.5 ) itself, it is necessary to escape the character with a backslash or quotes.
Therefore, every -exec
operator ends with the characters
The C shell
uses the characters
as both will sneak the semicolon past the shell and get it to the find command. As I said before, find can even call find . If you wanted to list every symbolic link in every directory owned by a group staff , you could execute:
To search for all files with group-write permission and remove the permission, you can use:
The difference between -exec and xargs is subtle. The first one will execute the program once per file, while xargs can handle several files with each process. However, xargs may have problems (9.22 ) with filenames that contain embedded spaces.
Occasionally people create a strange file that they can't delete. This could be caused by accidentally creating a file with a space or some control character in the name. find and -exec can delete this file, while xargs could not. In this case, use ls -il to list the files and i-numbers (1.22 ) , and use the -inum operator with -exec (23.16 ) to delete the file:
If you wish, you can use
which does the same as
except the program asks you first to confirm the action
before executing the command.
It is a good idea to be cautious when using
because the program can make a mistake into a disaster.
When in doubt, use
as the command.
Or send the output to a file and examine the file
before using the file as input to
This is how I discovered that
writes the filenames to its standard output.
loop and its
read the filenames from standard input, then make them
Articles 17.12 and 17.24 have more examples of -exec .