find -exec cmd {} + vs | xargs


回答:


107

速度の違いは重要ではありません。

ただし、次のことを確認する必要があります。

  1. スクリプトは、ファイル名にスペースやタブなどがないことを想定していません。最初のバージョンは安全ですが、2番目のバージョンは安全ではありません。

  2. スクリプトは、 " -"で始まるファイルをオプションとして扱いません。

したがって、コードは次のようになります。

find . -exec cmd -option1 -option2 -- {} +

または

find . -print0 | xargs -0 cmd -option1 -option2 --

最初のバージョンは1を無視できるので短くて簡単ですが、「-exec cmd {} +」はGNU findutilsの比較的新しいオプションであるため、2番目のバージョンは移植性と安全性が高くなっています(2005年以降、多くの実行中のシステムにはまだありません)。そして最近バギーでした。また-exec cmd {} +、他の回答からわかるように、多くの人がこれを知らない。


4
-print0は、GNU find(およびGNU xargs)オプションでもあり、Linux以外の多くのシステムにはないため、移植性の引数はそれほど有効ではありません。ただし、-printだけを使用し、xargsから-0を外しておくと、移植性非常に高くなります。
dannysauer、2009年

7
ポイントは、-print0がないと、スペースやタブなどが含まれるファイルがある場合は機能しないことです。これは、「foo -o index.html」のようなファイル名がある場合のように、-oが処理されるため、セキュリティの脆弱性になる可能性がありますオプションとして。空のディレクトリで試してください:「touch-foo \ -o \ index.html; find。| xargs cat」。「cat:invalid option
'o

2
彼の例は-を含むファイル名です。-print0がない場合、findは./foo -o index.htmlを吐き出します。したがって、-で始まることは大したことではないかもしれませんが、結果はほとんど変わりません。マルチユーザーシステムでは、スクリプトが誰でも読み取り可能であれば、攻撃ベクトルを提供する可能性があります。
bobpaul

2
ここで私をつまずかせた何かについてのメモ-を使用execするxargsと、見つかった結果が出力されますが、標準出力に書き込む前にディレクトリ全体が検索されるまで待機します。大きなディレクトリでこれを試してxargsいて、機能していないように見える場合は、忍耐をお勧めします。
FarmerGedden 2013

1
@Motivated findを使用しない-print0と、改行で区切られたファイル名が返されますが、改行はファイル名の一部になることもあり、あいまいになります。バイト0はできないので、安全な区切り文字です。はい- --それをサポートするコマンドに追加することは、常に厳密に要求されたり安全ではない場合でも、その引数を制御できない場合の良い習慣です。
Tometzky

7
find . | xargs cmd

より効率的です(一致ごとに1 cmd回実行されるとは異なりexec、実行回数は可能な限り少なくなりますcmd)。ただし、ファイル名にスペースやファンキーな文字が含まれていると、問題が発生します。

以下を使用することをお勧めします。

find . -print0 | xargs -0 cmd

これは、ファイル名がファンキーな文字が含まれている場合でも動作します(-print0なりますがfind、NUL終端マッチを印刷し-0ますが、xargsこのフォーマットを期待しています。)


28
これは「find。-exec cmd {} \;」ではありません。しかし、「。-exec cmd {} +を見つける」。後者は一度に1つのファイルを実行しません。
Tometzky、2009年

2
xargs一致するファイルが存在しない(または数個しか存在しない)場合、アプローチが実際には大幅に遅くなり、cmdファイルごとに行う必要のないことにも注意してください。たとえば、空のディレクトリで実行する場合、xargs1つではなく2つのプロセスを開始する必要があるため、バージョンにかかる時間は少なくとも2倍になります。(はい、通常、* nixでは違いはごくわずかですが、ループ内では重要になる可能性があります。または、Windowsでしばらく試してください...)
ごくわずか SamB

2

Modern xargsのバージョンは、多くの場合、並列パイプライン実行をサポートしています。

それは間の選択に来るとき明らかにそれはピボットポイントであるかもしれない find … -exec し、 … | xargs

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.