cheersmate
cheersmate

Reputation: 2666

Using find with printf and or

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

Answers (1)

DevSolar
DevSolar

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 that find . -name afile -o -name bfile -print will never print afile.

Upvotes: 2

Related Questions