回答:
速度の違いは重要ではありません。
ただし、次のことを確認する必要があります。
スクリプトは、ファイル名にスペースやタブなどがないことを想定していません。最初のバージョンは安全ですが、2番目のバージョンは安全ではありません。
スクリプトは、 " -
"で始まるファイルをオプションとして扱いません。
したがって、コードは次のようになります。
find . -exec cmd -option1 -option2 -- {} +
または
find . -print0 | xargs -0 cmd -option1 -option2 --
最初のバージョンは1を無視できるので短くて簡単ですが、「-exec cmd {} +
」はGNU findutilsの比較的新しいオプションであるため、2番目のバージョンは移植性と安全性が高くなっています(2005年以降、多くの実行中のシステムにはまだありません)。そして最近はバギーでした。また-exec cmd {} +
、他の回答からわかるように、多くの人がこれを知らない。
exec
するxargs
と、見つかった結果が出力されますが、標準出力に書き込む前にディレクトリ全体が検索されるまで待機します。大きなディレクトリでこれを試してxargs
いて、機能していないように見える場合は、忍耐をお勧めします。
-print0
と、改行で区切られたファイル名が返されますが、改行はファイル名の一部になることもあり、あいまいになります。バイト0はできないので、安全な区切り文字です。はい- --
それをサポートするコマンドに追加することは、常に厳密に要求されたり安全ではない場合でも、その引数を制御できない場合の良い習慣です。
find . | xargs cmd
より効率的です(一致ごとに1 cmd
回実行されるとは異なりexec
、実行回数は可能な限り少なくなりますcmd
)。ただし、ファイル名にスペースやファンキーな文字が含まれていると、問題が発生します。
以下を使用することをお勧めします。
find . -print0 | xargs -0 cmd
これは、ファイル名がファンキーな文字が含まれている場合でも動作します(-print0
なりますがfind
、NUL終端マッチを印刷し-0
ますが、xargs
このフォーマットを期待しています。)
xargs
一致するファイルが存在しない(または数個しか存在しない)場合、アプローチが実際には大幅に遅くなり、cmd
ファイルごとに行う必要のないことにも注意してください。たとえば、空のディレクトリで実行する場合、xargs
1つではなく2つのプロセスを開始する必要があるため、バージョンにかかる時間は少なくとも2倍になります。(はい、通常、* nixでは違いはごくわずかですが、ループ内では重要になる可能性があります。または、Windowsでしばらく試してください...)