home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 17.9 Problems with -newer Chapter 17
Finding Files with find
Next: 17.11 Using -exec to Create Custom Tests
 

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 \; . There is one more special argument that find treats differently: {} . These two characters are used as the variable whose name is the file find found. Don't bother rereading that last line. An example will clarify the usage. The following is a trivial case, and uses the -exec operator with echo (8.6 ) to mimic the -print operator:

% find . -exec echo {} \;

The C shell uses the characters { and } (9.5 ) , but doesn't change {} together, which is why it is not necessary to quote these characters. The semicolon must be quoted, however. Quotes can be used instead of a backslash:

% find . -exec echo {} ';'

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:

`...`
 
% find `pwd` -type d -group staff -exec find {} -type l -print \;

To search for all files with group-write permission and remove the permission, you can use:

-perm
 
% find . -perm -20 -exec chmod g-w {} \;

or:

% find . -perm -20 -print | xargs chmod g-w 

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:

% find . -inum 31246 -exec rm {} ';'

If you wish, you can use -ok which does the same as -exec , except the program asks you first to confirm the action before executing the command. It is a good idea to be cautious when using find , because the program can make a mistake into a disaster. When in doubt, use echo as the command. Or send the output to a file and examine the file before using the file as input to xargs . This is how I discovered that find requires {} to stand alone in the arguments to -exec . I wanted to rename some files using -exec mv {} {}.orig but find wouldn't replace the {} in {}.orig . I learned that I have to write a shell script (17.11 ) that I tell find to execute. [A little Bourne shell while loop (44.10 ) with redirected input (45.23 ) can handle that too:


>
 

$ find ... -print |


> while read file


> do mv "$file" "$file.orig"


> done

find writes the filenames to its standard output. The while loop and its read command (44.13 ) read the filenames from standard input, then make them available as $file , one by one. -JP  ]

Articles 17.12 and 17.24 have more examples of -exec .

- BB


Previous: 17.9 Problems with -newer UNIX Power Tools Next: 17.11 Using -exec to Create Custom Tests
17.9 Problems with -newer Book Index 17.11 Using -exec to Create Custom Tests

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System