Thursday, January 24, 2008

Delete All Files With Exceptions Using find

Gavin suggested a clever trick to recursively get the list of all the files in in a directory, except those under .svn. It goes like this:

find WEB-INF -path "*/.svn" -prune -o -print

I used this quite a bit, but never thought about how this really works, until today:

  • The -o is an or operator. So either -path "*/.svn" -prune or -print is true. Let's look at each part.
  • The first part -path "*/.svn" is true for the .svn directories and with -prune we skip the content of those directories.
  • If you just had the first part, you would be skipping over the content of the .svn directories, but not over the directory itself. The second part -print prints what isn't matched by the first part (because of the or). So it won't print the .svn directories.
For sure, this is not the most intuitive expression I have ever seen! Now we can extend this to do other things. For instance the expression below will delete all the files in the current directory, but it won't delete:
  • directories;
  • files in the CVS directories.
find . -path "*/CVS" -prune -o -type f -exec rm {} \;

This can be useful for instance when you have files checked out from CVS or Subversion and want to replace all your files by a copy of those files that you receive from someone in an archive.