Réponses:
L'interprétation du 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 est la responsabilité du shell (/ bin / sh ou équivalent).
Dans votre exemple, vous pouvez choisir d'utiliser votre shell de niveau supérieur pour effectuer la tuyauterie comme suit:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
En termes d'efficacité, ces résultats coûtent une invocation de find, de nombreuses invocations de zcat et une invocation d'agrément.
Cela entraînerait la création d'un seul processus d'accord qui traiterait toutes les sorties produites par de nombreuses invocations de zcat.
Si, pour une raison quelconque, vous souhaitez invoquer plusieurs fois agrép, vous pouvez:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Cela construit une liste de commandes à l'aide de canaux à exécuter, puis les envoie à un nouveau shell pour qu'elles soient réellement exécutées. (Omettre le "| sh" final est une bonne façon de déboguer ou d'effectuer des exécutions à sec de lignes de commande comme celle-ci.)
En termes d'efficacité, ce résultat coûte une invocation de find, une invocation de sh, de nombreuses invocations de zcat et de nombreuses invocations de entente.
La solution la plus efficace en termes de nombre d'appels de commandes 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 d'agrément.
-exec sh -c "… | … " \;
.
la solution est simple: exécutez via sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-c
option. Sinon, vous obtiendrez un No such file or directory
message d'erreur déroutant .
find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
Vous pouvez également diriger vers une while
boucle qui peut effectuer plusieurs actions sur le fichier qui find
se trouve. Voici donc un pour rechercher dans les jar
archives un fichier de classe java donné dans un dossier avec une grande distribution de jar
fichiers
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 while
boucle contient plusieurs commandes référençant le nom de fichier transmis séparé par un point-virgule et ces commandes peuvent inclure des canaux. Donc, dans cet exemple, je fais écho au nom du fichier correspondant, puis j'énumère ce qui se trouve dans le filtrage d'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.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
dans mon shell bash (xubuntu10.04 / xfce), il rend vraiment le nom de classe correspondant en gras car il fgrep
met en évidence la chaîne correspondante; cela rend très facile de parcourir la liste des centaines de jar
fichiers qui ont été recherchés et de voir facilement toutes les correspondances.
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 commandes est '&' not ';' et que le '@' supprime l'écho de la commande pour donner une sortie ordonnée tout comme la sortie de recherche Linux ci-dessus; bien que findstr
ne rende pas la chaîne correspondante en gras, vous devez donc regarder un peu plus près la sortie pour voir le nom de la classe correspondante. Il s'avère que la commande windows 'for' connaît pas mal de trucs comme la boucle dans les fichiers texte ...
prendre plaisir
J'ai trouvé que l'exécution d'une commande de shell de chaîne (sh -c) fonctionne mieux, par exemple:
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
Si vous cherchez une alternative simple, cela peut être fait en utilisant une boucle:
for i in $(find -name 'file_*' -follow -type f);do zcat $i | agrep -dEOE 'grep');done
ou, forme plus générale et facile à comprendre:
for i in $(YOUR_FIND_COMMAND);do YOUR_EXEC_COMMAND_AND_PIPES );done
et remplacez tout {} par $ i dans YOUR_EXEC_COMMAND_AND_PIPES