¿Cómo incluyo una pipa? en mi Linux buscar comando -exec?
Esto no funciona. ¿Se puede hacer esto en buscar? ¿O necesito xargs?
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
la solución es fácil: ejecutar vía sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
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.
También puede canalizar a un while
bucle que puede realizar múltiples acciones en el archivo que find
lo ubica. Así que aquí hay uno para buscar en jar
archivos un archivo de clase Java determinado 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 while
bucle 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 fgrep
resaltar la cadena coincidente; esto hace que sea realmente fácil escanear la lista de cientos de jar
archivos 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 findstr
no 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
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'" \;