Code Comments
Programming Forum and web based access to our favorite programming groups.Despite several experiments I still can't quite understand how the -prune option of find works. So can someone give me some examples ? Assume that I want to omit directories dir1 , dir2 , dir3. How should I write the find command ? Spiros Bousbouras
Post Follow-up to this messagespibou@gmail.com wrote On 07/17/06 16:03,: > Despite several experiments I still can't quite understand how > the -prune option of find works. So can someone give me some > examples ? Assume that I want to omit directories dir1 , dir2 , > dir3. How should I write the find command ? find foo \( -type d -name dir\[123\] -prune \) -o -type f -print This lists all the regular files in the foo hierarchy, excluding any descendants of directories named dir1, dir2, or dir3. Note that the exclusion applies at all containment levels: foo/dir1/* and foo/bar/dir2/* and foo/bar/baz/dir3/* are all excluded. -- Eric.Sosman@sun.com
Post Follow-up to this messageEric Sosman wrote: > spibou@gmail.com wrote On 07/17/06 16:03,: > > find foo \( -type d -name dir\[123\] -prune \) -o -type f -print > > This lists all the regular files in the foo hierarchy, > excluding any descendants of directories named dir1, dir2, > or dir3. Note that the exclusion applies at all containment > levels: foo/dir1/* and foo/bar/dir2/* and foo/bar/baz/dir3/* > are all excluded. Hmmm , the general principle still eludes me. The way I read the above command is Print all files below foo which satisfy \( -type d -name dir\[123\] -prune \) or are regular files So this should print all regular files. I mean -o is the or operator, right ? It seems to me that if you want to omit some files *and* print the rest, you should use the -a flag. However a bit of experi- mentation shows that your construction is correct and does what is supposed to do. So what am I missing ? Is it necessary to include -print in the command you gave ? Can you rewrite the example giving the 3 directory names explicitly ie without using the dir\[123\] shorthand ?
Post Follow-up to this messagespibou@gmail.com wrote On 07/17/06 17:02,: > Eric Sosman wrote: > > > > > Hmmm , the general principle still eludes me. The way I read > the above command is > > Print all files below foo which > satisfy \( -type d -name dir\[123\] -prune \) > or > are regular files > > So this should print all regular files. I mean -o is the or operator, > right ? It seems to me that if you want to omit some files *and* > print the rest, you should use the -a flag. However a bit of experi- > mentation shows that your construction is correct and does what > is supposed to do. So what am I missing ? The special effect of -prune, which is "don't pursue this branch any further." So when -type d declares "This is a directory" and -name dir\[123\] days "with the name dir1, dir2, or dir3," the -prune says "don't search inside this directory." The search never enters the excluded directory so its contents are never even looked at, much less handed to the stuff after -o. > Is it necessary to include -print in the command you gave ? I don't know. In early versions of find, it certainly was: without some kind of action (-print, -exec, ...), find would just locate the files and do nothing. Later, some find variants were enhanced to supply an implicit -print if no other action was specified, but I've never bothered to find out whether this enhancement was ever standardized or has become widespread. I know what I want find to do with the files it locates, and I'm not shy about telling it. > Can you rewrite the example giving the 3 directory names > explicitly ie without using the dir\[123\] shorthand ? Untested: find foo \( -type d \( -name ford -o -name arthur \ -o -name zaphod \) \ -prune \) \ -o type f -print Like APL programs, find commands can be "write-only." -- Eric.Sosman@sun.com
Post Follow-up to this messageIn article <1153170155.963687.173460@p79g2000cwp.googlegroups.com>, "spibou@gmail.com" <spibou@gmail.com> wrote: > Eric Sosman wrote: > > > Hmmm , the general principle still eludes me. The way I read > the above command is > > Print all files below foo which > satisfy \( -type d -name dir\[123\] -prune \) > or > are regular files No, the -print option is only applied to the second branch of the -o. The first branch, which contains the -prune, does not contain -print, so nothing is printed for files that match that branch. > > Is it necessary to include -print in the command you gave ? I don't think so. If there are no action options anywhere in the command, the default is to assume -print at the very end. > Can you rewrite the example giving the 3 directory names > explicitly ie without using the dir\[123\] shorthand ? Replace -name dir\[123\] with \( -name dir1 -o -name dir2 -o -name dir3 \) -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
Post Follow-up to this messagespibou@gmail.com wrote:
> Eric Sosman wrote:
>
>
> Hmmm , the general principle still eludes me. The way I read
> the above command is
>
> Print all files below foo which
> satisfy \( -type d -name dir\[123\] -prune \)
> or
> are regular files
It's a lazy "or", like C's "||" operator.
Lazy "or" (and "and") operators, although they have a truth value,
also act like conditionals. So this C code:
foo() || bar();
has a program flow like this:
if (!foo())
bar();
In the above, bar() is only executed if foo() is false. You
don't need to execute bar() if foo() evaluates to true, because
"True OR X" is true regardless of whether X is true or false.
Likewise, this C code:
foo() && bar();
has a program flow like this:
if (foo()) { bar(); }
and for similar reasons.
Getting back to the "find" command, the last several arguments
also form an expression:
-name 'dir[123]' -prune
-o
-type f -print
This can be further expanded since the first two tests ("-name"
and "-prune") and the last two tests ("-type" and "-print") have
an implied "and" between them, making the above equivalent to
this (parenthesized to indicate order of operations -- yes, "find"
does apply precedence rules and doesn't just evaluate left to
right):
( -name 'dir[123]' -a -prune )
-o
( -type f -a -print )
Now, "-prune" and "-print" are tests, but they are tests in a
bit of a degenerate way, because they always pass. Their purpose
is only to have side effects. So, the lazy operators will have
a program flow like this:
if name matches 'dir[123]'
then
prune
else
if type is 'f'
then
print
endif
endif
Hope that helps.
- Logan
Post Follow-up to this messageThanks everyone , I believe I've got it now. Spiros Bousbouras
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.