回答:
パイプ記号を複数のプロセスを実行し、あるプロセスの出力を別のプロセスの入力にパイプする命令として解釈する作業は、シェル(/ bin / shまたは同等のもの)の責任です。
あなたの例では、トップレベルのシェルを使用して次のようにパイプを実行することを選択できます:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
効率の面では、この結果、findの1回の呼び出し、zcatの多数の呼び出し、およびagrepの1回の呼び出しにコストがかかります。
これにより、zcatの多数の呼び出しによって生成されたすべての出力を処理する単一のagrepプロセスのみが生成されます。
何らかの理由で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の数回の呼び出し、およびagrepの1回の呼び出しにかかるコスト。
解決策は簡単です:sh経由で実行
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-c
オプションを見落とさないようにしてください。そうしないと、不可解なNo such file or directory
エラーメッセージが表示されます。
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'
検索while
して、ファイルに対して複数のアクションを実行できるループにパイプすることもできfind
ます。だからここにjar
、jar
ファイルの大きなディストリビューションを持つフォルダ内の特定のJavaクラスファイルのアーカイブを探すためのものがあります
find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done
重要な点は、while
ループにはセミコロンで区切られた渡されたファイル名を参照する複数のコマンドが含まれており、これらのコマンドにはパイプを含めることができるということです。したがって、その例では、一致するファイルの名前をエコーしてから、特定のクラス名のアーカイブフィルタリングの内容を一覧表示します。出力は次のようになります。
/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
私のbashシェル(xubuntu10.04 / xfce)ではfgrep
、一致した文字列が強調表示されるため、一致したクラス名が実際に太字になります。これにより、jar
検索された何百ものファイルのリストを簡単にスキャンして、一致を簡単に見つけることができます。
Windowsでは、次のように同じことができます。
for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList
Windowsでは、コマンドセパレータは「;」ではなく「&」であることに注意してください。また、 '@'はコマンドのエコーを抑制して、上記のlinux findの出力と同じように整然とした出力を提供します。ただしfindstr
、一致した文字列を太字にしないため、一致したクラス名を表示するには、出力を少し詳しく確認する必要があります。ウィンドウの「for」コマンドは、テキストファイルのループなど、かなりの数のトリックを知っていることがわかります...
楽しい
文字列シェルコマンド(sh -c)を実行すると、次のように最もうまく機能することがわかりました。
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;