Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to use the find command in Unix and I know how to use the basics of it. For example, I have four folders, A, B, C, and D. Under each folder I have a file called hi.dat. To look in all folders, I would do:

find * -name hi.dat.

Great! But now what if I do not want to look at folder D? Can I try something like:

find * not D/* -name hi.dat?

I do not want to type:

find A/* B/* C/* -name ... because I obviously have more than three folders and those were just used as an example.

Thanks! Amit

share|improve this question

3 Answers 3

up vote 10 down vote accepted

In Bash:

shopt -s extglob
find !(D) -name hi.dat

Ksh and zsh work similarly.

share|improve this answer
    
oh man. so do I type this in the command line? –  Amit Mar 17 '11 at 21:42
3  
@Amit: Yes, where else? The extglob option may already be set. You can check by doing shopt extglob, if it says "on", you're set. If not, you can add the shopt -s extglob to your ~/.bashrc and it will be set for you when you start Bash. Once it's set by any of those methods, all you need to type is the find command. –  Dennis Williamson Mar 17 '11 at 21:46
    
@Dennis: This is actually very convenient. So if I type what you wrote, this looks in all current files/directories under where I am currently located? –  Amit Mar 17 '11 at 22:07
    
Oh this works like a charm. SO much easier to remember. –  Amit Mar 17 '11 at 22:08
    
Could you elaborate a little more using this technique? What if I now didn't want A and D? How would that be written? –  Amit Mar 17 '11 at 22:09

That would be -prune — but there's a slight trick to it:

$ find . \( -name D -prune \) -o -name hi.dat

-prune means "don't look any further on this path", so you need another branch for directories other than D. (-o means "or".) To skip other paths as well:

$ find . \( \( -name D -o -name Dminor \) -prune \) -o -name hi.dat
share|improve this answer
    
excellent, this worked!! Thank you. –  Amit Mar 17 '11 at 21:44
    
+1 [to fill min] –  Amit Mar 17 '11 at 22:08

A more general find command is

find -path ./D -prune -o -name hi.dat -print

Caveat: the -path test might not yet be portable/part of a POSIX standard.

Rationale: In a directory structure like the following

$ find
.
./D
./A
./A/D
./A/D/hi.dat

compared to

$ find . \( -name D -prune \) -o -name hi.dat
./D
./A/D

it will only list the files actually searched for (explicit -print) and it will not omit files in subdirectories also named D (-path):

$ find -path ./D -prune -o -name hi.dat -print
./A/D/hi.dat
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.