How do I stop a find from descending into found directories?

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 "$@" … -exec … {\} +
' _ {} +

- 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.

Tags:

Find

Recursive