Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I find every file and directory matching a pattern, excluding one directory using find?

Say I have the following file structure;

.
  foo-exclude-me/
    foo.txt
  foo-exclude-me-not/
    foo.txt
  bar/
    foo.txt
    foobar/
      bar.txt
      foofoo.txt

how would I get the following output using find:

./bar/foo.txt
./bar/foobar
./bar/foobar/foofoo.txt
./foo-exclude-me-not
./foo-exclude-me-not/foo.txt

I have tried using both of the following command:

find . -name 'foo-exclude-me' -prune -o -name 'foo*'
find . -name 'foo*' \! -path './foo-exclude-me/*'

but both of them return this:

./bar/foo.txt
./bar/foobar
./bar/foobar/foofoo.txt
./foo-exclude-me # << this should be excluded
./foo-exclude-me-not
./foo-exclude-me-not/foo.txt

How can I properly exclude the foo-exclude-me directory?

share|improve this question
    
Try using foo-exclude-me instead of ./foo-exclude-me. Also try appending -print at the end of the command. –  maxmackie Mar 7 '13 at 17:55
    
@MaxMackie perfect :) –  Tyilo Mar 7 '13 at 18:00
    
It fixed it? Which was the fix that worked for you? I can put it in an answer instead of a comment. –  maxmackie Mar 7 '13 at 18:01
    
@MaxMackie using both -print and foo-exclude-me instead of ./foo-exclude-me. –  Tyilo Mar 7 '13 at 18:04
    
Awesome, looks like Gilles beat me to it though :) –  maxmackie Mar 7 '13 at 18:13

1 Answer 1

up vote 5 down vote accepted
find . -name 'foo-exclude-me' -prune -o -name 'foo*' -print

With no -print, the implicit default action applies to every match, even pruned ones. The explicit -print applies only under the specified conditions, which are -name 'foo*' only in the else branch of -name 'foo-exclude-me'.

Generally speaking, use an explicit -print whenever you're doing something more complex than a conjunction of predicates.

Your second attempt with ! -path './foo-exclude-me/*' didn't work because ./foo-exclude-me doesn't match ./foo-exclude-me/* (no trailing /). Adding ! -path ./foo-exclude-me would work.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.