2つの異なる実行可能ファイルを使用して、ディレクトリ内の一連のファイルを処理する検索コマンドを作成しようとしています。残念ながら、-exec
findでは、パイプまたは\|
は、シェルがその文字を最初に解釈するためです。
具体的には、私がやろうとしていることをここに示します(パイプがfindコマンドを終了するため動作しません):
find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
これを試して
find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print
別の方法として、shスクリプト内にexecステートメントを埋め込み、次に実行することもできます。
find -exec some_script {} \;
少し異なるアプローチは、xargsを使用することです。
find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123
私は常に少し理解しやすく、適応しやすいと感じました(空白を含むファイル名に対処するには、-print0引数と-0引数が必要です)
このmight(テストなし)は、-execを使用するよりも効果的です。ファイルのリストをxargsにパイプするため、xargsはjheadコマンドラインが長くなりすぎないようにします。
-exec
を使用すると、任意のシェルコマンドではなく、いくつかの引数を持つ単一の実行可能ファイルのみを実行できます。これを回避するには、sh -c '<Shell command>'
を使用できます。
-exec
の使用は非常に非効率的であることに注意してください。見つかったファイルごとに、コマンドを再度実行する必要があります。これを回避できれば、より効率的です。 (たとえば、grep
を-exec
の外側に移動するか、 Palmin で提案されているようにfind
の結果をxargs
にパイプすることによって。)
このタイプのタスクにfind
コマンドを使用することは、おそらく最良の選択肢ではありません。次のコマンドを頻繁に使用して、要求された情報を含むファイルを見つけます。
for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
これはリストを出力するので、あなたはそうしません:
find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123
または
find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123
Find -execの結果にgrepを追加します。
別の方法もありますが、かなりゲットーです。
Shellオプションのextquoteを使用すると、execのものを見つけてshにパイプするために、これと同様のことができます。
root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename
root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h
少なくとも私がそれを視覚化した方法では、exec内でパイプを使用するというOPの元々の質問に近かったからです。