Para o registro, aqui está a abordagem que eu prefiro:
grep pattern $(find . -type f ! -path './test/main.cpp')
Mantendo o grepcomando no início do comando, acho que isso é um pouco mais claro - além de não desabilitar grepo realce de cores. Em certo sentido, usar finduma substituição de comando é apenas uma maneira de estender / substituir o subconjunto (limitado) de pesquisa de arquivos da grepfuncionalidade de.
Para mim, a find -execsintaxe é meio misteriosa. Uma complexidade find -execé a (às vezes) necessidade de escapar vários caracteres (principalmente se \;for usado no Bash). Apenas para fins de colocar as coisas em contextos familiares, os dois comandos a seguir são basicamente equivalentes:
find . ! -path ./test/main.cpp -type f -exec grep pattern {} +
find . ! -path ./test/main.cpp -type f -print0 |xargs -0 grep pattern
Se você deseja excluir subdiretórios , pode ser necessário usar um curinga. Eu não entendo completamente o esquema aqui - fale sobre arcano :
grep pattern $(find . -type f ! -path './test/main.cpp' ! -path './lib/*' )
Uma observação adicional para generalizar findsoluções baseadas em uso em scripts : A greplinha de comando deve incluir a opção -H/ --with-filename. Caso contrário, ele alterará a formatação da saída sob a circunstância de que exista apenas um nome de arquivo nos resultados da pesquisa find. Isso é notável porque não parece ser necessário se você estiver usando grepa pesquisa de arquivos nativa (com a -ropção).
... Melhor ainda, é incluir /dev/nullcomo primeiro arquivo a pesquisar. Isso resolve dois problemas:
- Ele garante que, se houver um arquivo para pesquisar,
greppensará que existem dois e use o modo de saída de vários arquivos.
- Ele garante que, se não houver arquivos para pesquisar,
greppensará que existe um arquivo e não ficará esperando no stdin.
Portanto, a resposta final é:
grep pattern /dev/null $(find . -type f ! -path './test/main.cpp')
--exclude-dir). É por isso que eu gostaria que o grep execute a exclusão de forma nativa.