Supposing we're using find in current directory with audio files (e. g. MP3) and (important!) also non-mp3 files (e. g. JPEG) present in current directory or somewhere below it.
Additionally to that, we have a directory in there with some other audio files
(called exclude_me in the example), which should live up to its name by being excluded from the file search:
find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -iname '*.mp3' -a -print \)
(Though not absolutely necessary in this case, I've deliberately set some redundant parentheses, as well as additional -a
operators for the sake of clarity.)
Because of the explicit -print
option (cf. also http://mywiki.wooledge.org/UsingFind), this will indeed omit anything from "exclude_me" directory, and only list the *.mp3 files recursively from current directory.
Sometimes (not always) the alias
command may already be sufficient for a find
one-liner, but this command will require the argument at the end of the line.
Taking notice that the '*.mp3' argument to -iname is before the -print
in this case, there appears to be no way to solve the problem with an alias
.
But why not pretend as if in mathematics by simply swapping the two options?
Like this:
find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -print -a -iname '*.mp3' \)
Remember I set a precondition to have at least one non-mp3 file (e. g. image) in the . directory or its subdirectories. It has been set to give a clearer proof that this does not work as expected under the hood. Without them, things will merely look as working fine. Having them present instead will cause the non-mp3 files to get listed as well despite the distinct -iname '*.mp3'
specification in the one-liner.
So why doesn't the -a
operator work like in mathematics, where "A + B" is the same as "B + A"? Or, in find
terms:
\( -type f -a -print -a -iname '*.mp3' \)
ought to be the same as
\( -type f -a -iname '*.mp3' -a -print \)
or not?
Is there no way to get the desired result and have the -iname
argument at the end of the line, not anywhere in between?
(except for ugly hackish solutions like grep -v exclude_me
or the like)
-a
is never commutative, but with-print
you notice because-print
has side-effects.