## 9.25. Finding Files with -prune

find has lots of operators for finding some particular kinds of files. But find won't stop at your current directory -- if there are subdirectories, it looks there too. How can you tell it "only the current directory"? Use -prune.

Most finds also have a -maxdepth option that gives the maximum number of directory levels to descend. For example, find . -maxdepth 0 operates only on the current directory.

-prune cuts short find's search at the current pathname. So, if the current pathname is a directory, find won't descend into that directory for any further searches. The command line looks kind of hairy. Here's one to find all files modified in the last 24 hours from the current directory:

>     % date
>     Tue Feb 12 19:09:35 MST 2002
>     % ls -l
>     total 0
>     drwxr-xr-x  1 deb  deb  0 Feb 12 12:11 adir
>     -rw-r--r--  1 deb  deb  0 Feb 12 19:08 afile
>     -rw-r--r--  1 deb  deb  0 Jan 10 10:37 bfile
>     -rw-r--r--  1 deb  deb  0 Feb 11 22:43 cfile
>     % find . \( -type d ! -name . -prune \) -o \( -mtime -1 -print \)
>     ./afile
>     ./cfile

Let's try to understand this command: once you see the pattern, you'll understand some important things about find that many people don't. Let's follow find as it looks at a few pathnames.

find looks at each entry, one by one, in the current directory (.). For each entry, find tries to match the expression from left to right. As soon as some parenthesized part matches, it ignores the rest (if any) of the expression.[40]

> [40]That's because if one part of an OR expression is true, you don't need to check the rest. This so-called "short-circuit" logical evaluation by find is important to understanding its expressions.

When find is looking at the file named ./afile, the first part of the expression, ( -type d ! -name . -prune ), doesn't match (./afile isn't a directory). So find doesn't prune. It tries the other part, after the -o (or):

Has ./afile been modified in the last day? In this (imaginary) case, it has -- so the -print (which is always true) prints the pathname.

Next, ./bfile: like the previous step, the first part of the expression won't match. In the second part, ( -mtime -1 -print ), the file's modification time is more than one day ago. So the -mtime -1 part of the expression is false; find doesn't bother with the -print operator.

Finally, let's look at ./adir, a directory: the first part of the expression, ( -type d ! -name . -prune ), matches. That's because ./adir is a directory (-type d ), its name is not . (! -name .). So -prune, which is always true, makes this part of the expression true. find skips ./adir (because -prune prunes the search tree at the current pathname). Note that if we didn't use ! -name ., then the current directory would match immediately and not be searched, and we wouldn't find anything at all.

Section 9.27 shows handy aliases that use -prune.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.