So I was trying to remove all the old backups created by emacs, and I knew there was a way to do this using the find command. If you want to just list all the backup files, then you simply type:
$ find . -name "*~"
./example.java~
./build/test/define.c~
and it will list all your backup files, or files that end in a '~'. Now if you want find to execute a command on each file that it finds, you have to use the -exec command. Here's a clip from the man page for find.
-exec command ;
Execute command; true if 0 status is returned. All
following arguments to find are taken to be
arguments to the command until an argument
consisting of ‘;’ is encountered.
This is great, but from the description it seems like this is what you need to do:
$ find . -name "*~" -exec echo ;
I expect that this will simply print each file's name on standard output. However, it doesn't instead it returns:
$ find . -name "*~" -exec echo ;
find: missing argument to `-exec'
In order to get it to work the way you expect, you have to escape the semi-colon by adding a '\' in front of it. Here's the output you get:
$ find . -name "*~" -exec echo \;
All this does is print a blank line on standard output. If you want it to print the file's name, then you have to use '{}' braces and the file name will be inserted for each invocation of the command. Here is the final version, with two exec commands, the first prints out what we're going to do and the second executes the command.
$ find . -name "*~" -exec echo "rm {}" \; -exec rm {} \;
rm ./libpath.sh~
rm ./classpath.sh~
rm ./test/Makefile~
Another way to do this is to use a for loop like this:
$ for fileName in $( find . -name "*~" ); do \
echo "rm $fileName"; \
rm $fileName; \
done
I think this approach is a little more flexible if you have more complicated commands. You can also pipe the output of find to other commands in order to filter the results. For example:
$ for fileName in $( find . -name "*~" | grep -v java ); do \
echo "rm $fileName"; \
rm $fileName; \
done
This will exclude all files that have the word java in their name.