¿Cómo puedo incluir un pipe / en mi comando linux find-exec?


Esto no está funcionando. ¿Se puede hacer esto en find? O necesito xargs?

find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
Author: someguy, 2008-11-21

4 answers

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 elegir usar su shell de nivel superior para realizar la tubería de la siguiente 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 sería el resultado es que solo se genera un único proceso agrep que procesaría toda la salida producida por numerosas invocaciones de zcat.

Si por alguna razón 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 pipes para ejecutar, luego los envía a un nuevo shell para que realmente se ejecute. (Omitir el "| sh " final es una buena manera de depurar o realizar simulacros de líneas de comandos como esta.)

En términos de eficiencia esto resulta 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, unas pocas invocaciones de zcat y una invocación de agrep.

 120
Author: Rolf W. Rasmussen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-18 12:56:17

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

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
 214
Author: flolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-08 16:08:28
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
 15
Author: Paul Tomblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-21 15:09:47

También puede canalizar a un bucle while que puede realizar múltiples acciones en el archivo que find localiza. Así que aquí hay uno para buscar en los archivos jar un archivo de clase java dado en una carpeta con una gran distribución de jar archivos

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 bucle while contiene múltiples comandos que hacen referencia al nombre de archivo pasado separado por punto y coma y estos comandos pueden incluir tuberías. Así que en ese ejemplo echo el nombre del archivo coincidente y luego enumero lo que está en el archivo filtrado para un nombre de clase dado. La salida se ve como:

/usr/lib/eclipse/plugins/org.eclipsar.núcleo.contenttype.source_3. 4. 1.R35x_v20090826-0451.frasco /usr/lib/eclipse/plugins / org.eclipsar.núcleo.databinding.observable_1. 2. 0.M20090902-0800.frasco org / eclipse/core/databinding/observable/list / IObservableList.clase /usr/lib/eclipse/plugins / org.eclipsar.búsqueda.source_3. 5. 1.r351_v20090708-0800.frasco /usr/lib/eclipse/plugins / org.eclipsar.jdt.apt.núcleo.source_3. 3. 202.R35x_v20091130-2300.frasco /usr/lib/eclipse/plugins / org.eclipsar.cvs.source_1. 0. 400.v201002111343.frasco /usr/lib/eclipse/plugins / org.eclipsar.ayudar.appserver_3.1. 400.v20090429_1800.jar

En mi shell bash (xubuntu10.04/xfce) realmente hace que el nombre de clase coincidente se ponga en negrita ya que el fgrep resalta la cadena coincidente; esto hace que sea muy fácil escanear la lista de cientos de archivos jar que se buscaron y ver fácilmente cualquier coincidencia.

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 órdenes es ' & 'not'; 'y que el' @ ' suprime el eco de la orden para dar una salida ordenada al igual que la salida de linux find arriba; aunque findstr no es hacer la cadena coincidente en negrita por lo que tiene que mirar un poco más de cerca a la salida para ver el nombre de la clase coincidente. Resulta que el comando ' for ' de Windows conoce bastantes trucos como bucear a través de archivos de texto...

Disfruta

 8
Author: simbo1905,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-18 22:15:32