pipeline como o argumento -exec do find

4

É possível usar um comando de pipeline como um argumento para encontrar a opção -exec ? Isso significa que eu quero fazer algo assim:

find . -name CMakeLists* -exec cat '{}' | grep lib \;

onde estou tentando executar cat '{}' | grep lib para cada arquivo, mas isso não funciona. Nem citando trabalho. Alguém tem algum conselho?

Atualização:

A questão em particular foi respondida. Agora, existe uma maneira de um padrão genérico find <path> -type f -name <name> -exec <pipeline-command> funcionar?

    
por FloHe 09.01.2017 / 23:39

2 respostas

8
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.

    
por 09.01.2017 / 23:48
2

Em primeiro lugar, não é assim que o comando find termina.

Em segundo lugar, você pode simplesmente substituir cat por grep lib .

find . -name CMakeLists* -exec grep lib '{}' \;

Que basicamente significa "executar grep lib" em cada um dos resultados da pesquisa. Você pode até mesmo omitir os carrapatos em torno de {}. Deve funcionar.

    
por 09.01.2017 / 23:46