it-swarm-pt.tech

Como uso um pipe no parâmetro exec para um comando find?

Estou tentando construir um comando find para processar um monte de arquivos em um diretório usando dois executáveis ​​diferentes. Infelizmente, -exec on find não permite usar pipe ou mesmo \| porque o Shell interpreta esse caractere primeiro.

Aqui está especificamente o que estou tentando fazer (o que não funciona porque o pipe termina o comando find):

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
72
hoyhoy

Tente isto

find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print

Como alternativa, você pode tentar incorporar sua instrução exec em um script sh e, em seguida, fazer:

find -exec some_script {} \;
79
Martin Marconcini

Uma abordagem ligeiramente diferente seria usar xargs:

find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123

que eu sempre achei um pouco mais fácil de entender e adaptar (os argumentos -print0 e -0 são necessários para lidar com nomes de arquivos que contêm espaços em branco)

Isso pode (não testado) é mais eficaz do que usar -exec, pois canalizará a lista de arquivos para xargs e xargs garante que a linha de comando do jhead não seja muito longa.

12
Palmin

Com -exec você pode executar apenas um único executável com alguns argumentos, não com comandos arbitrários do Shell. Para contornar isso, você pode usar sh -c '<Shell command>'.

Observe que o uso de -exec é bastante ineficiente. Para cada arquivo encontrado, o comando deve ser executado novamente. Seria mais eficiente se você puder evitar isso. (Por exemplo, movendo grep para fora de -exec ou canalizando os resultados de find para xargs conforme sugerido por Palmin .)

3
mweerden

Usar o comando find para esse tipo de tarefa talvez não seja a melhor alternativa. Eu uso o seguinte comando frequentemente para encontrar arquivos que contêm as informações solicitadas:

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
3
Dimitar

Como isso gera uma lista, você não faria:

find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123

ou

find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123

Coloque seu grep nos resultados do find -exec.

1
Xetius

Existe uma outra maneira de fazer isso, mas também é um gueto bonito.

Usando a opção Shell extquote, você pode fazer algo semelhante a isso para fazer com que o Find Exec seja executado e depois direcionado para sh.

[email protected] findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


[email protected] findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

Imaginei que acrescentaria isso porque, pelo menos da maneira como o visualizei, estava mais próximo da questão original do OP de usar pipes dentro de exec.

0
linuxgeek