web-dev-qa-db-fra.com

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

Ça ne marche pas. Cela peut-il être fait en trouver? Ou ai-je besoin de xargs?

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

Le travail consistant à interpréter le symbole de canal comme une instruction pour exécuter plusieurs processus et diriger la sortie d’un processus vers l’entrée d’un autre processus relève de la responsabilité de Shell (/ bin/sh ou l’équivalent).

Dans votre exemple, vous pouvez choisir d'utiliser votre shell de niveau supérieur pour effectuer la tuyauterie de la manière suivante:

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

En termes d’efficacité, cela se traduit par une invocation de find, de nombreuses invocations de zcat et une invocation d’accordp.

Cela se traduirait par la création d'un seul processus Agrand qui traiterait toutes les sorties générées par de nombreuses invocations de zcat.

Si, pour une raison quelconque, vous souhaitez invoquer agrép plusieurs fois, vous pouvez effectuer les opérations suivantes:

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

Ceci construit une liste de commandes utilisant des tubes à exécuter, puis les envoie à un nouveau shell pour être réellement exécutées. (Omettre le "| sh" final est un bon moyen de déboguer ou de procéder à des exécutions à blanc de lignes de commande comme celle-ci.)

En termes d’efficacité, cela coûte une invocation de find, une invocation de sh, de nombreuses invocations de zcat et de nombreuses invocations d’agrend.

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'

... ce qui coûte une invocation de find, une invocation de xargs, quelques invocations de zcat et une invocation de Agrep.

131
Rolf W. Rasmussen

la solution est simple: exécuter via sh

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
249
flolo
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
16
Paul Tomblin

Vous pouvez également diriger vers une boucle while qui peut effectuer plusieurs actions sur le fichier que find localise. En voici donc une pour rechercher dans jar archives pour un fichier de classe Java) dans un dossier avec une grande distribution de 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 faisant référence au nom de fichier transmis, séparées par un point-virgule, ces commandes pouvant inclure des canaux. Ainsi, dans cet exemple, je renvoie le nom du fichier correspondant à la liste, puis répertorie le contenu du filtrage des archives pour un nom de classe donné. La sortie ressemble à:

/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.M200902-08 .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/Elipse/plugins/org.Eclipse.cvs.source_1.0.400.v2010013113.jar/usr /lib/Eclipse/plugins/org.Eclipse.help.appserver_3.1.400.v20090429_1800.jar

dans mon shell bash (xubuntu10.04/xfce), le nom de classe correspondant est en gras, car fgrep met en surbrillance la chaîne correspondante; il est donc très facile de parcourir la liste des centaines de fichiers jar qui ont été recherchés et de voir facilement les correspondances éventuelles.

sur Windows, vous pouvez faire la même chose avec:

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

notez que dans Windows, le séparateur de commande est '&' not ';' et que le '@' supprime l'écho de la commande pour donner une sortie ordonnée tout comme le résultat de recherche de Linux ci-dessus; bien que findstr ne mette pas la chaîne correspondante en gras, vous devez donc regarder de plus près à la sortie pour voir le nom de la classe correspondante. Il s'avère que la commande 'for' de Windows connaît pas mal de trucs comme faire des boucles dans des fichiers texte ...

prendre plaisir

9
simbo1905