find -exec command {} + のコマンドラインはどのように構築されますか?

find -exec command {} + のコマンドラインはどのように構築されますか?

のマニュアルの説明はfind少しわかりにくいと思います。

「ただし、コマンド ラインは選択された各ファイルを末尾に追加することによって構築されるため、コマンドの呼び出しの合計数は、一致したファイルの数よりもはるかに少なくなります」とはどういう意味ですか? なぜでしょうか?

以下はman find

-execコマンド{} +

この-execアクションのバリアントは、選択されたファイルに対して指定されたコマンドを実行しますが、コマンド ラインは、選択された各ファイル名を末尾に追加することによって構築されます。コマンドの呼び出しの合計数は、一致したファイルの数よりもはるかに少なくなります。コマンド ラインは、xargsコマンド ラインの構築方法とほぼ同じ方法で構築されます。コマンド内では、'{}' のインスタンスは 1 つだけ使用できます。コマンドは開始ディレクトリで実行されます。

答え1

「ただし、コマンド ラインは選択された各ファイルを末尾に追加することによって構築されるため、コマンドの呼び出しの合計数は、一致したファイルの数よりもはるかに少なくなります」とはどういう意味ですか? なぜでしょうか?

サンプルファイルをいくつか作成してみましょう。

touch {1..5}.txt

まず、find コマンドを実行してみましょう。

$ find . -exec echo my files are: {} +
my files are: . ./1.txt ./5.txt ./4.txt ./3.txt ./2.txt

ご覧のとおり、見つかった{}すべてのファイルのリストに置き換えられますfind。この例では、一致したファイルは 6 つありますが、echo実行は 1 回だけです。

シェルには、1 つのコマンド ラインで受け入れる文字数に制限があることに注意してください。 は findこれを認識しており、1 つのコマンド ラインに入力できるファイルが多すぎる場合は、すべてのファイル名が処理されるまで、異なるファイルで複数回find実行しますecho。これが、「コマンドの呼び出し回数が、一致するファイルの数よりはるかに少なくなる」理由です。

ディレクトリ内に多数のファイルを作成してこれをテストしてみましょう。

touch this_is_a_long_file_name{1..10000}.txt

それでは、find コマンドを実行してみましょう。

$ find . -exec bash -c 'echo $# files on this command line' _ {} +
3756 files on this command line
3754 files on this command line
2491 files on this command line

ご覧のとおり、このディレクトリには 10,000 を超えるファイルがあったにもかかわらず、exec コマンドは 3 回しか実行されませんでした。

関連情報