web-dev-qa-db-ja.com

find -exec + vs find | xargs:どれを選択するか?

-exec+オプションはxargsの動作を模倣します。ある形式を他の形式よりも好む状況はありますか?

私は個人的には、パイプを使用しないようにするためだけに、最初の形式を好む傾向があります。きっと、findの開発者は適切な最適化を行っているはずです。私は正しいですか?

33
rahmu

あなたが見つけるために呼び出しをチェーンしたいかもしれません(一度、あなたが学んだとき、それは今日かもしれない可能性があるということです)。もちろん、これはあなたが見つけ続けている間だけ可能です。パイプをxargsに渡すと、スコープ外になります。

小さな例、2つのファイルa.lstとb.lst:

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

ここではトリックはありません-単に両方とも「fuddel」を含んでいるのに、一方だけが「fiddel」を含んでいるという事実です。

それを知らなかったとしましょう。 2つの条件に一致するファイルを検索します。

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097    4 -rw-r--r--   1 stefan   stefan         20 Jun 27 17:05 ./a.lst

まあ、多分あなたは両方の文字列を条件として渡すためのgrepや他のプログラムの構文を知っていますが、それはポイントではありません。引数としてファイルを指定すると、trueまたはfalseを返すことができるすべてのプログラムをここで使用できます-grepは一般的な例にすぎません。

また、find -execの後に、-ls-のような他の検索コマンドを続けることができますdeleteまたは同様のもの。 deleteはrm(ファイルを削除する)だけでなく、rmdir(ディレクトリを削除する)も行うことに注意してください。

そのようなチェーンは、特に指定されていない限り(つまり、-orスイッチ(および括弧(マスキングが必要))で)、コマンドのAND組み合わせとして読み取られます。

そのため、便利なことですが、検索チェーンを離れることはありません。 -xargsを使用する利点はありません。ファイルの受け渡しには注意が必要です。ファイルを渡す必要はありません。これは、各ファイルの受け渡しを単一の引数として自動的に処理します。

検索結果のマスキングが必要だと思われる場合 {}中括弧 、証拠を求める私の質問に気軽にアクセスしてください。私の主張は:あなたはそうではありません。

22
user unknown

ファイル名をxargsに安全にパイプするには、find-print0オプションをサポートし、xargsがそれを読み取るための対応するオプション(--nullまたは-0)。そうしないと、名前に印刷できない文字、バックスラッシュ、引用符、または空白が含まれるファイル名が予期しない動作を引き起こす可能性があります。一方、find -exec {} +POSIX find spec に含まれるため、移植可能であり、find -print0 | xargs -0とほぼ同じくらい安全で、間違いなく安全です。 find | xargsより。 find | xargsを使用せずに-print0を行うことは決してしないことをお勧めします。

26
jw013

-exec ... ;形式(セミコロンをエスケープすることを忘れないでください)を使用する場合、ファイル名ごとにコマンドを1回実行します。 -print0 | xargs -0を使用する場合、ファイル名ごとに複数のコマンドを実行します。 -exec +形式を必ず使用してください。これは、単一のコマンドラインに複数のファイルを配置し、多数のファイルが関係する場合にはるかに高速です。

xargsを使用する大きな利点は、xargs -Pを使用して複数のコマンドを並行して実行できることです。マルチコアシステムでは、時間を大幅に節約できます。

11
Alexios

パフォーマンスに関しては、-exec … +はすべての作業を行う単一のツールであるため、単により良いと思いました GNU findutilのドキュメントの一部-exec … +は、場合によっては効率が低下する可能性があります。

[-exec … +]で検索は、xargsの一部の使用よりも効率が悪い場合があります。たとえば、xargsを使用すると、前のコマンドの実行中に新しいコマンドラインを構築でき、並行して実行するコマンドの数を指定できます。ただし、find ... -exec ... +構成には、移植性が高いという利点があります。 GNU findutilsは、バージョン4.2.12[2005年1月];まで、 '-exec ... +'をサポートしていませんでした。1つこれは、いずれの場合も「-print0」アクションがすでにあったためです。

私はそれが何を意味するのか正確にわからなかったので、私はチャットで尋ねました derobert はそれを次のように説明しました:

findは、-exec … +の実行中に次のファイルのバッチの検索を続行できる可能性がありますが、そうではありません。
find … | xargs …は実行します。これは、検索が別のプロセスであり、パイプバッファーがいっぱいになるまで実行が継続されるためです。

(私によるフォーマット。)

それがあります。ただし、パフォーマンスが本当に重要な場合は、現実的なベンチマークを行うか、そのような場合にシェルを使用するかどうかを自問する必要があります。

ここのこのサイトでは、単純であることと、他の回答で説明されている理由(たとえば、あまり考えずに奇妙なファイル名を処理すること)のために、可能な限り-exec … +フォームを使用するように人々に助言することをお勧めします。

8
phk