Tente adicionar as expressões entre parênteses, conforme indicado na man page:
find . -type f \( -name '*.c' -or -name '*.h' -or -name '*.cpp' \) -exec ls {} \;
deve funcionar.
Eu quero executar um comando para cada arquivo que corresponda a um padrão. Mas o comando que parece estar certo, não funciona para mim, não tenho ideia do porquê.
$ find . -type f -name '*.c' -or -name '*.h' -or -name '*.cpp' -exec ls {} \;
$ ls
script.sh test.c test.h
Com GNU find
, você pode usar a opção -regex
:
find . -type f -regex '.*\.\(c\|h\|cpp\)' -exec ls {} \;
Você pode tentar usar find -D tree . [expr..]
para entender o que encontrar com seu comando original.
Você deve entender que as expressões -type f
e também -exec ls ..
são and
'ed para o restante das expressões com precedência mais alta que a or
s.
Portanto, seu comando original será analisado em algo parecido com isto: (-type f AND -name *.c) OR -name *.h OR (-name *.cpp AND -exec ls)
(observe que o ou é realmente binário e não ternário, portanto, a | b | c
é, na verdade, (a | b) | c
, mas você entendeu).
Agora você notará que find não sabe o que fazer, exceto os arquivos que combinam *.cpp
, pois não há nenhuma declaração válida nos outros casos (é por isso que você pode ver um segfault ou algo semelhante na saída de depuração).
Espero que isso torne mais claro para você por que você precisa dos parênteses.