パイプ記号を複数のプロセスを実行し、あるプロセスの出力を別のプロセスの入力にパイプする命令として解釈する作業は、シェル (/bin/sh または同等のもの) の役割です。
あなたの例では、次のようにパイピングを実行するために最上位シェルを使用することを選択できます。
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
効率という点では、この結果は、find の 1 回の呼び出し、zcat の多数の呼び出し、および agrep の 1 回の呼び出しのコストがかかります。
これにより、1 つの agrep プロセスのみが生成され、zcat の多数の呼び出しによって生成されたすべての出力が処理されます。
何らかの理由で agrep を複数回呼び出したい場合は、次のようにできます:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
これは、パイプを使用して実行するコマンドのリストを作成し、これらを新しいシェルに送信して実際に実行します。 (最後の "| sh" を省略することは、このようなコマンド ラインのデバッグまたはドライ ランを実行するための良い方法です。)
効率という点では、この結果は、find の 1 回の呼び出し、sh の 1 回の呼び出し、zcat の多数の呼び出し、および agrep の多数の呼び出しのコストがかかります。
コマンド呼び出しの数に関して最も効率的な解決策は、Paul Tomblin からの提案です:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... これには、find の呼び出し 1 回、xargs の呼び出し 1 回、zcat の呼び出し 2 回、agrep の呼び出し 1 回が必要です。
解決策は簡単です:sh 経由で実行
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;