¿Cómo incluyo una pipa? en mi Linux buscar comando -exec?

Resuelto someguy asked hace 16 años • 7 respuestas

Esto no funciona. ¿Se puede hacer esto en buscar? ¿O necesito xargs?

find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
someguy avatar Nov 21 '08 05:11 someguy
Aceptado

la solución es fácil: ejecutar vía sh

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
flolo avatar Nov 20 '2008 22:11 flolo

El trabajo de interpretar el símbolo de tubería como una instrucción para ejecutar múltiples procesos y canalizar la salida de un proceso a la entrada de otro proceso es responsabilidad del shell (/bin/sh o equivalente).

En su ejemplo, puede optar por utilizar su caparazón de nivel superior para realizar la tubería de esta manera:

find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'

En términos de eficiencia, este resultado cuesta una invocación de find, numerosas invocaciones de zcat y una invocación de agrep.

Esto daría como resultado que se generara un solo proceso agrep que procesaría toda la salida producida por numerosas invocaciones de zcat.

Si por algún motivo desea invocar agrep varias veces, puede hacer:

find . -name 'file_*' -follow -type f \
    -printf "zcat %p | agrep -dEOE 'grep'\n" | sh

Esto construye una lista de comandos usando canalizaciones para ejecutar, luego los envía a un nuevo shell para que realmente se ejecuten. (Omitir el "| sh" final es una buena forma de depurar o realizar simulacros de líneas de comando como esta).

En términos de eficiencia, este resultado cuesta una invocación de find, una invocación de sh, numerosas invocaciones de zcat y numerosas invocaciones de agrep.

La solución más eficiente en términos de número de invocaciones de comandos es la sugerencia de Paul Tomblin:

find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'

... lo que cuesta una invocación de find, una invocación de xargs, algunas invocaciones de zcat y una invocación de agrep.

Rolf W. Rasmussen avatar Nov 20 '2008 22:11 Rolf W. Rasmussen

También puede canalizar a un whilebucle que puede realizar múltiples acciones en el archivo que findlo ubica. Así que aquí hay uno para buscar en jararchivos un archivo de clase Java determinado en una carpeta con una gran distribución de jararchivos.

find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done

el punto clave es que el whilebucle contiene múltiples comandos que hacen referencia al nombre del archivo pasado separados por punto y coma y estos comandos pueden incluir tuberías. Entonces, en ese ejemplo, hago eco del nombre del archivo coincidente y luego enumero lo que hay en el filtro de archivo para un nombre de clase determinado. La salida se parece a:

/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2.0.M20090902-0800 .jar org/eclipse/core/databinding/observable/list/ IObservableList .class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar /usr/lib/eclipse/plugins/ org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar /usr/lib/eclipse/plugins/ org.eclipse.help.appserver_3.1.400.v20090429_1800.jar

en mi shell bash (xubuntu10.04/xfce) realmente pone el nombre de clase coincidente en negrita para fgrepresaltar la cadena coincidente; esto hace que sea realmente fácil escanear la lista de cientos de jararchivos que se buscaron y ver fácilmente las coincidencias.

En Windows puedes hacer lo mismo con:

for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList

tenga en cuenta que en Windows el separador de comandos es '&' no ';' y que '@' suprime el eco del comando para dar una salida ordenada como la salida de búsqueda de Linux anterior; aunque findstrno pone la cadena coincidente en negrita, por lo que debe mirar un poco más de cerca la salida para ver el nombre de la clase coincidente. Resulta que el comando 'for' de Windows conoce bastantes trucos, como recorrer archivos de texto en bucle...

disfrutar

simbo1905 avatar Sep 18 '2010 12:09 simbo1905

Descubrí que ejecutar un comando de shell de cadena (sh -c) funciona mejor, por ejemplo:

find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
Andrew Khoury avatar Nov 28 '2019 06:11 Andrew Khoury