Die Aufgabe, das Pipe-Symbol als Anweisung zu interpretieren, mehrere Prozesse auszuführen und die Ausgabe eines Prozesses in die Eingabe eines anderen Prozesses zu leiten, liegt in der Verantwortung der Shell (/bin/sh oder gleichwertig).
In Ihrem Beispiel können Sie entweder Ihre Top-Level-Shell verwenden, um die Verrohrung wie folgt auszuführen:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
In Bezug auf die Effizienz kostet dieses Ergebnis einen Aufruf von find, zahlreiche Aufrufe von zcat und einen Aufruf von agrep.
Dies würde dazu führen, dass nur ein einziger agrep-Prozess gestartet wird, der die gesamte Ausgabe verarbeiten würde, die durch zahlreiche Aufrufe von zcat erzeugt wird.
Wenn Sie agrep aus irgendeinem Grund mehrmals aufrufen möchten, können Sie Folgendes tun:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Dies erstellt eine Liste von Befehlen, die auszuführende Pipes verwenden, und sendet diese dann an eine neue Shell, um tatsächlich ausgeführt zu werden. (Das Weglassen des abschließenden „| sh“ ist eine nette Art, Kommandozeilen wie diese zu debuggen oder Probeläufe durchzuführen.)
In Bezug auf die Effizienz kostet dieses Ergebnis einen Aufruf von find, einen Aufruf von sh, zahlreiche Aufrufe von zcat und zahlreiche Aufrufe von agrep.
Die effizienteste Lösung in Bezug auf die Anzahl der Befehlsaufrufe ist der Vorschlag von Paul Tomblin:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... was einen Aufruf von find, einen Aufruf von xargs, ein paar Aufrufe von zcat und einen Aufruf von agrep kostet.
Die Lösung ist einfach:Ausführen über sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;