Sometimes during my work I need to remove a set of files from a big directory tree. For example when I develop a driver or an application and I want to distribute to my customers only the obj files and the documentation files (README.txt, INSTALL.txt, LICENSE.txt, Makefile ……) I need to remove all my source code (*.c and *.h), this is a very tedious task, but I can use the bash to do this task for me, and I’m quite sure that bash doesn’t forget any files.

The secret is to use the find command in conjunction with the rm command, in the following I show you two ways to do this:

  1. find with exec

# find ./ -name "*.c" -exec rm -f {} \;

All following arguments to find are taken to be arguments to the rm command until an argument consisting of ‘;’ is encountered. The string {} is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.

With the -f option, the rm command ignore nonexistent files and never prompts the user. This could be very dangerous, so if you are not sure that you want to remove all th C files add the i option to rm, in this way rm will ask you if you want to remove the current file for each file in the directory tree.

# find ./ -name "*.c" -exec rm -fi {} \;

  2. find in pipe with rm

# find ./ -name "*.c" -print | xargs rm -f

xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is /bin/echo, in this case "rm -f") one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.

Naturally, also in this case, you can apply the -i option for the rm command.

# find ./ -name "*.c" -print | xargs rm -fi

Now imagine you want to remove all the files of an user, you can use the find command with the -user option to select each file of the specified user, then you could use one of the two methods above

# find ./ -user <userid> -exec rm -fi {} \;
# find ./ -user <userid> -print | xargs rm -fi