Pergunta

Estou tentando construir um comando find para processar vários arquivos em um diretório usando dois executáveis ​​​​diferentes.Infelizmente, -exec no 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
Foi útil?

Solução

Experimente isso

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

Alternativamente, você pode tentar incorporar sua instrução exec dentro de um script sh e então fazer:

find -exec some_script {} \;

Outras dicas

Uma abordagem um pouco diferente seria usar xargs:

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

que 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 contendo espaços em branco)

Esse poder (não testado) será mais eficaz do que usar -exec porque canalizará a lista de arquivos para xargs e xargs garante que a linha de comando do jhead não fique muito longa.

Com -exec você só pode executar um único executável com alguns argumentos, e não comandos shell arbitrários.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ê pudesse evitar isso.(Por exemplo, movendo o grep fora da -exec ou canalizando os resultados de find para xargs como sugerido por palmito.)

Usando find comando para este tipo de tarefa talvez não seja a melhor alternativa.Eu uso o seguinte comando frequentemente para encontrar arquivos que contenham as informações solicitadas:

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

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

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 de find -exec.

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

Usando a opção shell extquote você pode fazer algo semelhante a isso para encontrar coisas exec e depois canalizá-las para sh.

root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

Eu apenas pensei em acrescentar isso porque, pelo menos da maneira como visualizei, estava mais próximo da questão original do OP de usar pipes dentro do exec.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top