The patterns used with the -name
predicate in find
are standard filename globbing patterns. What you are trying to use is a brace expansion, which find
does not support.
Note that there is no single standard globbing pattern that matches filenames that end with .c
, .h
or .cpp
.
You might have wanted to use something like '*.'{c,h,cpp}
, which expands to *.c
, *.h
, and *.cpp
, but that does not include the -name
predicate nor the -o
.
The next thing to try is '-o -name "*.'{c,h,cpp}'"'
, but this expands to the three strings -o -name "*.c"
-o -name "*.h"
, and
-o -name "*.cpp"
. This also can't be used as you would have to split them on spaces to get find
to recognize the separate substrings (and remove the -o
from the first one). It would possibly work with eval
though, but it seems like more hassle than it's worth.
Instead of that, you may use two -name
tests with an OR in-between:
find "$directory" -type f \( -name '*.[ch]' -o -name '*.cpp' \) \
-exec clang-format -i {} +
This uses two -name
tests as described earlier (-o
is the OR operator), and also calls clang-format
as few times as possible by passing batches of found pathnames to the tool rather than invoking it once for each file.
With a tiny extra bit of programming, you may store all the filename suffixes that you want to pick up in a list, and create the needed find
expression from that.
Since you did not mention what shell you're using, I'm doing this for the POSIX sh
shell:
set -- c h cpp
for suffix do
set -- "$@" -o -name "*.$suffix"
shift
done
shift # shifts off the initial "-o"
find "$directory" -type f ( "$@" ) -exec clang-format -i {} +
or
set --
for suffix in c h cpp; do
set -- "$@" -o -name "*.$suffix"
done
shift
find "$directory" -type f ( "$@" ) -exec clang-format -i {} +
The list that "$@"
expands to in this example would be the equivalent of
-name '*.c' -o -name '*.h' -o -name '*.cpp'
find
supports -regex you can dofind . -regex "\./.*\.[c|h]"
– Arkadiusz Drabczyk Dec 05 '21 at 20:21[c|h]
would match one character from the setc
,|
, andh
. – Kusalananda Dec 05 '21 at 20:34find . -regex "\./.*\.[c,h]"
– Arkadiusz Drabczyk Dec 05 '21 at 20:44[c,h]
matches a comma. You mean(c|h)
, but that misses out oncpp
, so you end up with(c|h|cpp)
. Unfortunately though, rugelar expressions are non-standard when used withfind
and we don't even know what Unix the user is using let alone whatfind
implementation thay have. – Kusalananda Dec 05 '21 at 20:49