web-development-kb-es.site

¿Cómo uso una tubería en el parámetro exec para un comando de búsqueda?

Estoy tratando de construir un comando de búsqueda para procesar un grupo de archivos en un directorio usando dos ejecutables diferentes. Desafortunadamente, -exec on find no permite usar pipe o incluso \| porque el Shell interpreta ese carácter primero.

Aquí está específicamente lo que estoy tratando de hacer (que no funciona porque la tubería termina el comando de búsqueda):

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

Prueba esto

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

Alternativamente, podría intentar incrustar su declaración exec dentro de un script sh y luego hacer:

find -exec some_script {} \;
78
Martin Marconcini

Un enfoque ligeramente diferente sería utilizar xargs:

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

que siempre encontré un poco más fácil de entender y adaptar (los argumentos -print0 y -0 son necesarios para hacer frente a los nombres de archivos que contienen espacios en blanco)

Este podría (no probado) ser más efectivo que usar -exec porque canalizará la lista de archivos a xargs y xargs se asegura de que la línea de comandos de jhead no sea demasiado larga.

12
Palmin

Con -exec solo puede ejecutar un único ejecutable con algunos argumentos, no comandos de Shell arbitrarios. Para evitar esto, puedes usar sh -c '<Shell command>'.

Tenga en cuenta que el uso de -exec es bastante ineficiente. Para cada archivo que se encuentre, el comando debe ejecutarse nuevamente. Sería más eficiente si pudieras evitar esto. (Por ejemplo, moviendo el grep fuera del -exec o canalizando los resultados de find a xargs como lo sugiere Palmin .)

3
mweerden

El uso del comando find para este tipo de tarea tal vez no sea la mejor alternativa. Utilizo el siguiente comando con frecuencia para encontrar archivos que contienen la información solicitada:

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

Como esto da como resultado una lista no:

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

o

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

Pon tu grep en los resultados del hallazgo -exec.

1
Xetius

Hay otra forma de hacerlo, pero también es bastante gueto.

Usando la opción de Shell extquote, puedes hacer algo similar a esto para hacer que encuentres cosas ejecutables y luego canalizarlas a 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

Me imaginé que lo agregaría porque, al menos de la forma en que lo visualicé, estaba más cerca de la pregunta original de OP de usar tuberías dentro de exec.

0
linuxgeek