Eu escrevi anteriormente um script que pesquisa uma árvore de diretórios por arquivos .h e .c e, em seguida, executa o formato clang neles:
find $directory -name '*.[hc]' -exec clang-format -i {} \;
Isso funciona exatamente como esperado. Agora eu gostaria de adicionar arquivos .cpp à pesquisa. No entanto, nem
-name '*.{[hc],cpp}'
nem
-name '{*.[hc],*.cpp}'
trabalhar. Ou seja, eles não encontram arquivos.
Eu sei que eu poderia fazer minha lógica funcionar se eu usasse find
a -o
opção de . No entanto, deve haver uma maneira de fazer isso com uma única -name
diretiva.
Os padrões usados com o
-name
predicado infind
são padrões de globbing de nome de arquivo padrão. O que você está tentando usar é uma expansão de chave, quefind
não suporta.Observe que não há um único padrão de globbing padrão que corresponda a nomes de arquivos que terminam com
.c
,.h
ou.cpp
.Você pode querer usar algo como
'*.'{c,h,cpp}
, que se expande para*.c
,*.h
e*.cpp
, mas isso não inclui o-name
predicado nem o-o
.A próxima coisa a tentar é
'-o -name "*.'{c,h,cpp}'"'
, mas isso se expande para as três strings-o -name "*.c"
-o -name "*.h"
e-o -name "*.cpp"
. Isso também não pode ser usado, pois você teria que dividi-los em espaços parafind
reconhecer as substrings separadas (e remover a-o
da primeira). Ele possivelmente funcionaria comeval
, mas parece mais incômodo do que vale a pena.Em vez disso, você pode usar dois
-name
testes com um OR intermediário:Isso usa dois
-name
testes conforme descrito anteriormente (-o
é o operador OR) e também chamaclang-format
o menor número de vezes possível passando lotes de nomes de caminho encontrados para a ferramenta em vez de invocá-lo uma vez para cada arquivo.Com um pouco mais de programação, você pode armazenar todos os sufixos de nome de arquivo que deseja pegar em uma lista e criar a
find
expressão necessária a partir disso.Como você não mencionou qual shell está usando, estou fazendo isso para o
sh
shell POSIX:ou
A lista que
"$@"
se expande para neste exemplo seria o equivalente a-name
suporta padrões que não são diferentes de globs de shell, mas não suporta chaves (que a página man do GNU find menciona explicitamente), nem globs estendidos no estilo ksh.Mas muitos
find
s suportam o-regex
, e você pode usar isso. Dependendo de quais dialetos de regex, seusfind
suportes são, como regexes básicos padrão não suportam alternância.Com o GNU find, isso deve funcionar:
(Observe também que a correspondência existe em todo o caminho, não apenas na parte do nome do arquivo, mas se você estiver correspondendo apenas ao sufixo final do nome do arquivo, isso não será um problema.)