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.

I'm wanting to find all directories with a specific string so I can do another find on the files contained within.

So I don't want to waste time on ./my-search-term/dir/my-search-term etc.

How can I stop recursing when I've found the first my-search-term directory?

share|improve this question
2  
Have you tried find with -prune? From the man page: "if the file is a directory, do not descend into it. If -depth is given, false; no effect. Because -delete implies -depth, you cannot usefully use -prune and -delete together." –  laebshade Nov 13 '11 at 22:52
1  
@laebshade why don't you put that in an answer? –  jw013 Nov 13 '11 at 23:15
    
@jw013 I didn't have the time to provide a more indepth answer at that time. –  laebshade Nov 19 '11 at 19:01

2 Answers 2

up vote 4 down vote accepted

The -prune action makes find not recurse into the directory. You can combine it with another action such as -exec (the order of -prune and -exec doesn't matter, as long as -prune is executed either way).

find . -name my-search-term -prune -exec find {} … \;

Note that nesting find inside a find -exec can be a little problematic: you can't use -exec in the inner find, because the terminator would be seen as a terminator by the outer find. You can work around that by invoking a shell, but beware of quoting.

find . -name my-search-term -prune -exec sh -c '
    find "$0" … -exec … {} +
' {} \;
share|improve this answer
    
Are the parentheses in your first command necessary? -prune returns true and can be put before the -exec. –  rozcietrzewiacz Nov 14 '11 at 1:01
    
@rozcietrzewiacz No, they're not necessary. Habit of having a -o in there, I guess. And I guess putting -prune before -exec is more readable. –  Gilles Nov 14 '11 at 1:03

- bare solutions -

If you want find to skip the found directory's contents, but continue searching in other directories, use -prune as @laebshade suggested. The full command should then look like

 find . -type d -name somename -prune -exec ...

On the other hand, if you want find to entirely stop searching and after finding the first matching directory, then what you are looking for is -quit (available since version 4.2.3 of GNU find). This one is a bit more tricky to use, because it makes find exit immediately - so -quit must be placed at the very end of the command:

find . -type d -name somename -exec ... -quit

For this to work as expected, one has to assure that the -exec returns true (in other words, a zero status). If you want the exit status of -exec to be ignored, so that -quit always works, you need a little trick:

find . -type d -name somename \( -exec ... -o -true \) -quit

or

find . -type d -name somename \( -exec ... -o -quit \)

or

find . -type d -name somename \( -exec ... , -quit \) # a comma before -quit

- some explanation -

The most important thing about how find works is that all the actions ("tests") are treated as logical predicates interpreted from left to right. Therefore, the last action (for example -quit) will only be performed if the whole previous part did not return false. By default, all tests are joined with logical "AND", the -o option changes the joint to "OR".

A tricky element of -o is that find can "optimize" your command and not run the -exec part if you type just

find . -type d -name somename -exec ... -o -quit

To cope with that, you can force find to evaluate all the predicates joned with "OR", by enclosing them within parentheses.

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.