0

I'm finding that some find commands I enter, ignore a lot of files, and only seem to work properly* if I do not pass an action at the end of the command.

I will use the following command as the base for this question:
find . -depth -name '*.elf' -or -name '*.exe'

Real example:
find . -depth -name '*.elf' -or -name '*.exe' -or -name 'f*.xml' -or -name '*.html' -or -name '*.jar' -or -name '*.mat' -or -name '*.pyc' -or -name '*_dll' -or -name '*.class' -or -name '*.DS_Store' -or -name '*.dll' -or -name '*.dex'

The base command on its own gives plenty of output, but the following command does nothing*:
find . -depth -name '*.elf' -or -name '*.exe' -delete

Similarly, this command, though it should be identical to the base command, gives no output*:
find . -depth -name '*.elf' -or -name '*.exe' -print

Or even*:
find . -depth -name '*.elf' -or -name '*.exe' -exec echo {} \;

Am I missing something about how find works?

I'm using GNU find version 4.8.0.

*By "work properly", I mean that if I run the base command, I will find all matching files, but with any explicit action, only some consistent subset will be found. This means that if I pass -delete, that subset will be gone, and no explicit actions will find any of the remaining files. Reverting to the base command will find them again.

AI0867
  • 131
  • 4
  • How do I reply to suggestions that my question is a duplicate? The other question asks a very different question, though one of the answer indeed also answers my question. (I even linked to it in my answer!) – AI0867 Jan 27 '22 at 11:25

1 Answers1

0

Brackets

Apparently, actions become part of the or-expression, and only work for one of the branches, while removing the implicit print for all of them. (source)

The solution then, is to write the expression as follows, which encloses the or branches and ensures the action is not applied to just one branch:
find . -depth \( -name '*.elf' -or -name '*.exe' -or -name 'f*.xml' -or -name '*.html' -or -name '*.jar' -or -name '*.mat' -or -name '*.pyc' -or -name '*_dll' -or -name '*.class' -or -name '*.DS_Store' -or -name '*.dll' -or -name '*.dex' \)

Or the short form:
find . -depth \( -name '*.elf' -or -name '*.exe' \)

I'm still posting this question (plus the answer) because I couldn't find the right search terms to find the answer until I had finished writing the question. Hopefully this new question will help someone.

AI0867
  • 131
  • 4