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.