Reputation: 2666
I'm confused about using find
and combining -printf
with -o
. Say I have some files in a directory like
$ ls
a1 b1
and I want to use find
with two filters. Starting with AND:
find . -iname "a*" -iname "*1"
./a1
and using -printf
for counting:
find . -iname "a*" -iname "*1" -printf '.'
.
Seems fine. Now trying the same thing with an -o
to get the OR of the two filters:
$ find . -iname "a*" -o -iname "*1"
./b1
./a1
$ find . -iname "a*" -o -iname "*1" -printf '.'
.
Why don't I get ..
? Changing the order of arguments doesn't help:
$ find . -printf '.' -iname "a*" -o -iname "*1"
...
EDIT:
$ find . -type f \( -iname "a*" -o -iname "*1" \)
..
gives the expected behavior, see the accepted answer for an explanation.
Upvotes: 0
Views: 694
Reputation: 70372
See the section OPERATORS
of the find
man page:
OPERATORS
Listed in order of decreasing precedence:
( expr )
Force precedence. Since parentheses are special to the shell, you will normally need to quote them. Many of the examples in this manual page use backslashes for this purpose:
'\(...\)'
instead of'(...)'
.[...]
expr1 expr2
Two expressions in a row are taken to be joined with an implied "and"; expr2 is not evaluated if expr1 is false.
[...]
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
And then, emphasis mine:
Please note that
-a
when specified implicitly (for example by two tests appearing without an explicit operator between them) or explicitly has higher precedence than-o
. This means thatfind . -name afile -o -name bfile -print
will never print afile.
Upvotes: 2