1

I'm using GNU's find.

I've simplified my problem to this shell session:

$ mkdir t
$ cd t
$ touch a 
$ ln -s a b
$ find -type l
./b
$ find -type l -o -type f
./a
./b
$ find -type l -print
./b
$ find -type l -o -type f -print
./a

Maybe it's the fact that I'm very sleepy, but 2 things don't make sense to me:

  • Isn't true OR false == true? How is it that adding -o -type f causes find to stop matching ./b, despite -type l matching?
  • The manual page says that -print is the default expression, so how is it that a file is printed when it's not mentioned, but omitted when it is?

This also happens when using -printf (what I actually need); I imagine other expressions are affected, too.

JoL
  • 4,520
  • 15
  • 35
  • This too: [`find` with multiple `-name` and `-exec` executes only the last matches of `-name`](https://unix.stackexchange.com/questions/102191/find-with-multiple-name-and-exec-executes-only-the-last-matches-of-nam) – ilkkachu Apr 18 '17 at 08:59

1 Answers1

1

In

find -type l -o -type f -print

you’ve specified an action, so the default no longer applies. But -printf here is bound to -type f because “and” has a higher precedence than “or”; you can think of this as equivalent to

find \( -type l \) -o \( -type f -print \)

To process both links and files in the same way, you need to group the tests:

find \( -type l -o -type f \) -print
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • Now it makes sense why the manpage refers to `-print` as an expression; I had no idea actions could be mixed with predicates like `-type`, so I didn't know there were implicit `-a`s in there too. I'm accepting this answer as soon as the system lets me. – JoL Apr 18 '17 at 09:05