Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
up vote 11 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
    
Hi geekosaur. I have just down-voted your answer. Please have a look at the M. Meglio's answer. Hope this will motivate you to improve your answer. Then I may up-vote your answer... Cheers ;-) – olibre Oct 3 '14 at 16:32

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

It works piping grep -v,

$ find / -name "*~"|grep -v "/media"

looks everywhere but not inside media directory

share|improve this answer
    
It will look there but the results will be thrown away so this approach could be pretty inefficient when the paths to be omitted contain a lot of files and directories. – pabouk Sep 20 '14 at 21:36
    
In fact this is completely wrong approach, because /media can be subdirectory which you do not want to omit, moreover there could be (sub)directory /medial, /median etc, and in this solution you would throw away all those cases. – jimmij Sep 20 '14 at 22:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .