12

See below example:

$ ls -1p
appledir/
applefile
orangedir/
orangefile
$ find . -type f -name apple\*
./applefile
$ find . -type f -name orange\*
./orangefile
$ find . -type f -name apple\* -o -name orange\*
./applefile
./orangedir
./orangefile
$ find . -type f \( -name apple\* -o -name orange\* \)
./applefile
./orangefile
$ 

I was surprised to discover I needed the parentheses for this to work as expected; apparently I haven't internalized the rule of precedence by which find evaluates its arguments.

How can I easily predict when I will and when I will not need to use parentheses to explicitly group find primaries?

Put another way, what are the rules by which I can imagine find inserting parentheses into the commands I give it, which will allow me to accurately predict how it will evaluate ungrouped expressions?

Wildcard
  • 36,499

1 Answers1

13

As per the documentation,

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.

So basically you can imagine find surrounding any two "anded" expressions with parentheses by default. Your

find . -type f -name apple\* -o -name orange\*

is interpreted as

find . \( -type f -name apple\* \) -o -name orange\*
Stephen Kitt
  • 434,908
  • 1
    does this mean that find doesn't distinguish between test or action tokens? and simply looks at whether the operand evaluates true or false in the same way test would in a shell script? – the_velour_fog Aug 06 '16 at 10:41
  • 4
    @the_velour_fog that's right; in fact actions also return true or false depending on whether they succeed. – Stephen Kitt Aug 06 '16 at 12:25
  • ah thats what I struggled to understand, I always assumed that find would have treated test and action primaries differently, the way a compiler would recognise and treat variable types like array, int and string differently. but you really need to treat find like its a little programming language and manage the operators and operands yourself, thanks – the_velour_fog Aug 06 '16 at 12:36
  • 2
    @the_velour_fog, from Unix Power Tools, 3rd Edition: "find's business is evaluating expressions - not locating files. Yes, find certainly locates files; but that's really just a side effect. For me, understanding this point was the conceptual breakthrough that made find much more useful." – Wildcard Sep 28 '16 at 20:05
  • @wildcard, yes getting that its really a conditional expression evaluator is important. as per your question - and my challenge - was how do the rules work. comparing the find command to a shell conditional expression (although much more complicated than normal) is what my breakthrough was with find. It also helped with my general programming too. – the_velour_fog Sep 28 '16 at 20:24