This is from a mailing list post I’ve just replied to. Since I had to look it up, it’s worth blogging. 🙂
It seems like a simple task. Find all the files in the current directory, excluding .svn
directories. I’ve mocked up a simple layout.
% find . . ./.svn ./.svn/README.txt ./README.txt ./src ./src/.svn ./src/.svn/foo.c ./src/foo.c
By default, find prints out everything. But we only want files.
% find . -type f ./.svn/README.txt ./README.txt ./src/.svn/foo.c ./src/foo.c
Now, we want to exclude everything under .svn
. Easy.
% find . -name .svn -prune -type f
Ooops. That’s not good. What happened here? Well, the default for find is to and two expressions together. If we or it, we get what we want.
% find . -name .svn -prune -or -type f ./.svn ./README.txt ./src/.svn ./src/foo.c
Again, not so good. The problem is that default action to print everything. Because we’ve specified no action, it’ll print out each match, and that includes the .svn
directories (even though it correctly stops going into them).
The answer is to provide an explicit action instead.
% find . -name .svn -prune -or -type f -print ./README.txt ./src/foo.c
This works, because now there is no default action, and the explicit action is only associated with the -type f
predicate.
3 replies on “pruning your tree”
For things like this I always fall back on my ‘grep -v’ crutch:
find . -type f | grep -v \.svn
Me too. But I was determined to get to the bottom of it this time. 🙂
Also: you’ll need single quotes on the \.svn to get the backslash passed through properly. I normally don’t even bother with the backslash.
There’s also this awesome tool named ‘ack’: http://www.betterthangrep.com/