Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I found this weird behavior in find. Depending on the order of the parameters to find it finds different files.

For example, I have a directory tree with the following content.

.
├── configure.ac
├── Makefile.am
└── src
    ├── hello.c
    └── Makefile.am

if I run

find -name '*.cpp' -o -name '*.[chS]' -print0 | xargs -0 echo

It lists

./src/hello.c

And if I run

find -name '*.[chS]' -o -name '*.cpp' -print0 | xargs -0 echo

It doesn't list anything. Notice that the only thing I changed is the order of the file name.

Can anyone explain why the second command doesn't list any files?

share|improve this question
1  
Almost duplicate of unix.stackexchange.com/q/102191/22565 –  Stéphane Chazelas Apr 22 at 15:35

1 Answer 1

up vote 3 down vote accepted

The -print0 action gets bound only to the second -name "filter" (test in find parlance), so it will only print out something if the second filter matches. This is because the default operator in the find expression is and, and binds tighter than or (-o). i.e. your second expression is evaluated as:

find -name '*.[chS]' -o \( -name '*.cpp' -print0 \) | xargs -0 echo

Try grouping the filters:

find \( -name '*.[chS]' -o -name '*.cpp' \) -print0 | xargs -0 echo

You could also do this if you felt like it:

find -name '*.[chS]' -print0 -o -name '*.cpp' -print0 | xargs -0 echo
share|improve this answer
    
Huh, that would also explain why giving -print0 as the first parameter lists all the files. Makes sense, but it's also a bit unexpected. Thanks a lot :) –  Kotte Apr 22 at 15:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.