Excluding subdirectories using the find command
This question already has an answer here:
Following my previous comment, this works on my Debian :
find . -path ./ignored_directory -prune -o -name fileName.txt -print
or
find /path/to/folder -path "*/ignored_directory" -prune -o -name fileName.txt -print
or
find /path/to/folder -name fileName.txt -not -path "*/ignored_directory/*"
The differences are nicely debated here
To complement olivm's helpful answer and address the OP's puzzlement at the need for -o
:
-prune
, as every find
primary (action or test, in GNU speak), returns a Boolean, and that Boolean is always true
in the case of -prune
. -a
( -and
), which, like its brethren -o
( -or
) performs short-circuiting Boolean logic. -a
has higher precedence than -o
. For a summary of all find
concepts, see https://stackoverflow.com/a/29592349/45375
Thus, the accepted answer ,
find . -path ./ignored_directory -prune -o -name fileName.txt -print
is equivalent to (parentheses are used to make the evaluation precedence explicit):
find . ( -path ./ignored_directory -a -prune )
-o
( -name fileName.txt -a -print )
Since short-circuiting applies, this is evaluated as follows:
./ignored_directory
causes -prune
to be evaluated; since -prune
always returns true
, short-circuiting prevents the right side of the -o
operator from being evaluated; in effect, nothing happens (the input path is ignored) ./ignored_directory
, instantly - again due to short-circuiting - continues evaluation on the right side of -o
: fileName.txt
is the -print
primary evaluated; in effect, only input paths whose filename matches fileName.txt
are printed. Edit : In spite of what I originally claimed here, -print
IS needed on the right-hand side of -o
here; without it, the implied -print
would apply to the entire expression and thus also print for left-hand side matches; see below for background information.
By contrast, let's consider what mistakenly NOT using -o
does :
find . -path ./ignored_directory -prune -name fileName.txt -print
This is equivalent to:
find . -path ./ignored_directory -a -prune -a -name fileName.txt -a -print
This will only print pruned paths (that also match the -name
filter), because the -name
and -print
primaries are (implicitly) connected with logical ANDs;
in this specific case, since ./ignored_directory
cannot also match fileName.txt
, nothing is printed, but if -path
's argument is a glob, it is possible to get output.
A word on find
's implicit use of -print
:
POSIX mandates that if a find
command's expression as a WHOLE does NOT contain either
-print
itself -exec
and -ok
find
, but real-world implementations such as GNU find
and BSD find
add others, such as the output-producing -print0
primary, and the executing -execdir
primary) that -print
be applied implicitly, as if the expression had been specified as:
( expression ) -print
This is convenient, because it allows you to write commands such as find .
, without needing to append -print
.
However, in certain situations an explicit -print
is needed , as is the case here:
Let's say we didn't specify -print
at the end of the accepted answer:
find . -path ./ignored_directory -prune -o -name fileName.txt
Since there's now no output-producing or executing primary in the expression, it is evaluated as:
find . ( -path ./ignored_directory -prune -o -name fileName.txt ) -print
This will NOT work as intended, as it will print paths if the entire parenthesized expression evaluates to true, which in this case mistakenly includes the pruned directory.
By contrast, by explicitly appending -print
to the -o
branch, paths are only printed if the right-hand side of the -o
expression evaluates to true; using parentheses to make the logic clearer:
find . -path ./ignored_directory -prune -o ( -name fileName.txt -print )
If, by contrast, the left-hand side is true, only -prune
is executed, which produces no output (and since the overall expression contains a -print
, -print
is NOT implicitly applied).
Edit (added behavior specification details)
Pruning all permission denied directories in find
Using gnufind.
Specification behavior details - in this solutions we want to:
The basic design pattern is:
find ... ( -readable -o -prune ) ...
Example
find /var/log/ ( -readable -o -prune ) -name "*.1"
thanks{mklement0}
链接地址: http://www.djcxy.com/p/78124.html下一篇: 使用find命令排除子目录