I have few files under the current directory,
./a.txt
./b.txt
./dir1/c.txt
./dir1/d.txt
When I execute find . -path './dir1' -prune -o -name "*.txt"
,
as expected, it excludes everything under 'dir1' and prints,
./a.txt
./b.txt
./dir1
now if I switch the sequence of the subexpression and execute find . -name "*.txt" -o -path './dir1' -prune
,
to my understanding, it should have displayed all the files, as -name "*.txt"
subexpression should have matched everything that has .txt extension and just or
them with the following test. Therefore 'dir1' directory contents should not have been excluded. But that's doesn't seem to be the case. Displayed result is same as the previous one.
./a.txt
./b.txt
./dir1
what am I missing here?
My system is ubuntu-20.04. I have skim through the find man page and couldn't find any solution. Other sources in the web didn't provide with any satisfactory explanation either.
The -o
is not applied in a complete run of find
(ie, 'do all the things on the LH side of -o
and if nothing is found then do the RH side...)
Instead the -o
is file by file which is a big difference. Essentially you have this loop:
print
)The other thing going on here is no combination of -o
's or -a
's or parenthesis will overcome that -prune
has the highest precedence -- if a directory is listed with -prune
it is never visited.
If you want to do something along these lines:
find_like . LH_do_first --or RH_do_if_LH_finds_nothing
Then Bash is probably your best bet. Something along these lines:
lh=$(find . -name "*.txt")
cnt=$(awk '/[^[:blank:]]/{cnt++} END {print cnt}' <<<"$lh")
if (( cnt > 0 )); then
printf "%s" "$lh"
else
find . -path "./dir1" -prune
fi