Why doesn't find let me match multiple patterns?
find utility
-print
== default
If you just want to print file path and names, you have to drop exec echo
, because -print
is default.:
find . -name '*.html' -or -name '*.xml'
Order dependency
Otherwise, find
is read from left to right, argument order is important!
So if you want to specify something, respect and
and or
precedence:
find . -name '*.html' -exec echo ">"{} \; -o -name '*.xml' -exec echo "+"{} \;
or
find . -maxdepth 4 \( -name '*.html' -o -name '*.xml' \) -exec echo {} \;
Expression -print0
and xargs
command.
But, for most cases, you could consider -print0
with xargs
command, like:
find . \( -name '*.html' -o -name '*.xml' \) -print0 | xargs -0 printf -- "-- %s -\n"
The advantage of doing this is:
Only one (or few) fork for thousand of entry found. (Using
-exec echo {} \;
implies that one subprocess is run for each entry found, whilexargs
will build a long line with as many argument one command line could hold...)In order to work with filenames containing special character or whitespace,
-print0
andxargs -0
will use theNULL
character as the filename delimiter.
find ... -exec ... {} ... +
From some years ago, find
command accept a new syntax for -exec
switch.
Instead of \;
, -exec
switch could end with a plus sign +
.
find . \( -name '*.html' -o -name '*.xml' \) -exec printf -- "-- %s -\n" {} +
With this syntax, find
will work like xargs
command, building long command lines for reducing forks.