find -exec + vs find xargs:どちらを選択しますか?

find -exec + vs find xargs:どちらを選択しますか?

私は私が模倣-execできる行動があることを知っています。ある形式を他のものよりも好む状況はありますか?+xargs

私は個人的にパイプの使用を避けるために最初の形式を好みます。開発者がfind適切な最適化を行ったに違いないと思います。私は正しいですか?

答え1

ファイル名を安全にパイピングするxargsには、そのオプションをサポートし、それをfind読むための適切なオプション(または)が必要です。そうしないと、名前に印刷できない文字、バックスラッシュ、引用符、またはスペースを含むファイル名が予期しない動作を引き起こす可能性があります。一方、-print0xargs--null-0find -exec {} +POSIXfind仕様そのため、移植可能で同様に安全で、find -print0 | xargs -0より確実に安全ですfind | xargs。おすすめしたいいいえfind | xargsしなかった-print0

答え2

確認するために通話を接続したい場合があります(これが可能であることがわかったら、今日はそうかもしれません)。もちろん、これはまだ見続けるべきです。 xargs にパイプすると範囲外です。

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

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

ここにトリックはありません。どちらも「fuddel」を含みますが、1つだけが「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

さて、2つの文字列を条件として渡すgrepや他のプログラムの構文を知っているかもしれませんが、それは要点ではありません。 trueまたはfalse(ファイルを引数として提供)を返すことができるすべてのプログラムをここで使用できます。 grep は広く使われている例に過ぎません。

フォローすることができます。検索 - 実行次のような他の検索コマンドと一緒に使用されます。-lsまたは-削除またはそのようなもの。削除は、rm(ファイルの削除)操作だけでなく、rmdir(ディレクトリの削除)操作も実行できます。

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

したがって、ルックアップチェーンを離れないことは非常に便利です。 -xargs を使用すると、どのような利点も見つかりません。ファイルを渡すときは注意が必要だからです。これはfindが行う必要はありません。各ファイルを単一の引数として渡すことを自動的に処理します。

何か隠す必要があると思ったら{} 大きな括弧、私の質問にアクセスして証拠を求めてください。私の主張は:あなたは知らないということです。

答え3

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

使用の最大の利点の1つxargsは、複数のコマンドを並列に実行できることですxargs -P。マルチコアシステムでは、これにより多くの時間を節約できます。

答え4

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

[ で検索-exec … +]xargsたとえば、xargs古いコマンドの実行中に新しいコマンドラインを設定したり、複数のコマンドを並列に実行したりするなど、一部の用途よりも効率が悪い場合があります。しかし、このfind ... -exec ... +構造は移植性が広いという利点があります。 GNU findutils は-exec ... +バージョン 4.2.12 まで '' をサポートしていません。[2005年1月]; 1つの理由は、-print0とにかくすでに ""アクションがあるからです。

これがどういう意味なのかよく分からないのでチャットで聞いてみました。ドロバート次のように解釈されます。

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

(直接フォーマットしました。)

だからそれはすべてです。ただし、パフォーマンスが本当に重要な場合は、実際のベンチマークを実行するか、この状況でシェルを使用するかどうかを尋ねる必要があります。

このサイトでは、より簡単で、ここの他の回答で言及されている理由(たとえば、あまり考えないで奇妙なファイル名を処理できる)のため、可能な場合はいつでもその形式を使用するように人々にアドバイスするのが最善だと思います。-exec … +

関連情報