pruning your tree

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.

Comments 3

  1. Chris Winters wrote:

    For things like this I always fall back on my ‘grep -v’ crutch:


    find . -type f | grep -v \.svn

    Posted 27 Feb 2011 at 06:05
  2. Dominic Mitchell wrote:

    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.

    Posted 27 Feb 2011 at 09:10
  3. Steven Sproat wrote:

    There’s also this awesome tool named ‘ack’: http://www.betterthangrep.com/

    Posted 20 Apr 2011 at 11:45