261 votes

Comment puis-je inclure un tuyau | dans ma commande linux find -exec?

Cela ne fonctionne pas. Est-ce que cela peut être fait en trouver? Ou ai-je besoin de xargs?

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

355voto

flolo Points 8757

la solution est simple: exécuter via sh

 ... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
 

160voto

Rolf W. Rasmussen Points 803

Le travail de l'interprétation de la pipe comme une instruction d'exécuter plusieurs processus et le tuyau de la sortie d'un processus vers l'entrée d'un autre processus est de la responsabilité du shell (/bin/sh ou équivalent).

Dans votre exemple, vous pouvez soit choisir d'utiliser votre haut niveau shell pour effectuer la tuyauterie de la sorte:

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

En termes d'efficacité il en résulte des coûts d'une invocation de trouver, de nombreuses invocations de zcat, et une invocation de agrep.

Cela résulterait en une seule agrep processus d'être pondus qui traiterait de toutes les sorties produites par de nombreuses invocations de zcat.

Si vous pour une raison quelconque voudrais invoquer agrep plusieurs fois, vous pouvez le faire:

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

Ceci construit une liste de commandes à l'aide de tubes à effectuer, puis envoie un nouveau shell pour être réellement exécutées. (En omettant le dernier "| sh" est une belle façon de débogage ou d'effectuer des essais de lignes de commande comme ceci.)

En termes d'efficacité il en résulte des coûts d'une invocation de trouver, une invocation de poissons, de nombreuses invocations de zcat et de nombreuses invocations de agrep.

La solution la plus efficace en termes de nombre d'appels de commande est la suggestion de Paul Tomblin:

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

... qui coûte une invocation de trouver, une invocation de xargs, quelques invocations de zcat et une invocation de agrep.

16voto

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

11voto

simbo1905 Points 911

Vous pouvez aussi une pipe à une boucle while qui peut faire plusieurs actions sur le fichier qui localise. Voici donc un pour la recherche dans les archives jar pour un fichier de classe java dans le dossier avec une grande distribution de nombreux fichiers jar

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

le point clé étant que la boucle while contient plusieurs commandes de référencement du passé dans les noms de fichiers séparés par des point-virgules et ces commandes peuvent comprendre des tuyaux. Donc, dans ce cas, je reprends le nom du fichier correspondant puis la liste de ce qui est dans l'archive de filtrage pour un nom de classe. La sortie ressemble à ceci:

/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/liaison de données/observables/liste/IObservableList.classe /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

dans mon shell bash (xubuntu10.04/xfce) il n'a vraiment de la correspondance classname gras comme le fgrep faits saillants de la chaîne trouvée, ce qui rend vraiment facile à numériser vers le bas la liste des centaines de fichiers jar qui ont été fouillés et facilement voir les matchs dans ces fichiers.

si vous êtes sur windows, vous pouvez faire la même chose pour rechercher un nom de classe dans une butch de fichiers jar avec

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

notez que dans que sous windows la commande séparateur '&' pas ';' et le '@' supprime l'écho de la commande exécuter pour donner un ordre de sortie tout comme le linux de trouver la sortie ci-dessus; bien que findstr n'est pas de faire de la correspondance de chaîne en gras de sorte que vous avez à regarder un peu plus près à la sortie pour voir la correspondance nom de la classe. Il s'avère que le windows "pour" commande en sait quelques trucs comme la boucle via des fichiers texte...

profitez de

6voto

raphaelfournier Points 71

J'étais dans le cas de l'affiche originale, et la réponse choisie peut ne pas être satisfaisante, car vous ne voudrez peut-être pas que tout votre flux zcat passe par le canal sans distinguer le fichier d'origine.

Je pense donc que le ... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \; doit être mentionné et voté, à mon humble avis.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X