find . -type f -name "CMakeLists*" -exec grep lib /dev/null {} +
Isso encontra arquivos no diretório atual cujo nome de base começa ou é a string CMakeLists
. O argumento é escapado (double quoted) para que o shell não o expanda antes que find
seja executado.
Não há necessidade de adicionar cat
com um canal a grep
--- é um processo inútil com IO inútil, aqui. Adicionar /dev/null
garante que grep
reportará o nome do arquivo junto com a (s) linha (s) correspondente (s) quando houver mais de um arquivo para corresponder.
Usando {} +
como sequência de terminação para o argumento -exec
, vários nomes de arquivos são passados para cada chamada do comando grep
. Se tivéssemos usado {} \;
, então um processo grep
teria sido gerado para todos os arquivos encontrados. A instanciação desnecessária do processo é cara se feita centenas ou milhares de vezes.
Para usar um canal com um argumento find
-exec
, você precisa invocar o shell. Um exemplo planejado poderia ser grep
para a string "one", mas somente se a string "two" não estiver presente também. Isso pode ser feito como:
find . -type f -name "CMakeLists*" -exec sh -c 'grep one "$@"|grep -v two' sh {} +
Isso se baseia nos comentários abaixo, por @muru, @Serg e @Scott, com agradecimentos.