find コマンドを使用して行数を見つけます。

find コマンドを使用して行数を見つけます。

次の場所にあるRソースコードストアを検討してください。https://cloud.r-project.org/src/base/R-3/R-3.4.4.tar.gz。リポジトリをフォルダに解凍しました。さて、ディレクトリに何行があるのか​​知りたいです。だから私は次のコマンドを試しました。

find . -type f -exec wc -l {} \+

394968が生成されますが、次のコマンドを試した場合:

find . -type f -exec cat {} \+ | wc -l

1848857が生成されます!

似ているような2つのコマンド操作がなぜfindそんなに大きく異なる結果をもたらしますか?そして、ガジェットスクリプトを書くのではなく、コマンドラインユーティリティを使って行数を見つける正しい方法は何ですか?

答え1

最初に説明したコマンドは、find . -type f -exec wc -l {} +wc -lすべてのファイルが処理されるまでできるだけ多くのファイルを実行する」と言います。wc何度も実行できます!

一方、複数回find . -type f -exec cat {} + | wc -l実行できますが、一度だけcat実行されますwc。 (詳しくは、この場合、呼び出すと、必要catfind回数に関係なく実行することを決定でき、実行することにしました。パイプ文字の次の部分は範囲外ですので、wc -l実行findするかどうかはユーザーによって異なります。

最初のコマンドは「394968を生成します」と言いましたが、私のシステムでは、出力は次のように終了しません。

(Many more lines elided...)
     23 ./po/Makefile.win
     64 ./po/README
      1 ./VERSION-NICK
     97 ./README
 258450 total

ただし、追加すると実際に2回実行されるgrep totalことがわかりますwc

$ find . -type f -exec wc -l {} + | grep total
 1590407 total
 258450 total

実際、1590407に258450を加えると1848857になり、これは2番目のコマンドと一致します。


wcこのバージョンのコマンドが複数回実行される理由のあいまいなヒントの説明find -exec wc +マニュアルページを探す:

-exec command {} +

    この-execアクションのバリエーションは、選択したファイルに対して指定されたコマンドを実行しますが、コマンドラインは選択した各ファイル名を最後に追加することによって構成されます。コマンドの総呼び出し数は、一致するファイルの数よりはるかに少なくなります。コマンドラインは、xargsそのコマンドラインとほぼ同じ方法で構築されます。

これは、「一度だけ」ではなく、「...よりはるかに少ない」ことを意味します。これ xargsのドキュメントヒント--max-charsユーザーがオプションを設定しないと、自動的に設定されます。

--max-chars=max-chars
-s max-chars

    最もよく使うmax-charsコマンドと初期引数と引数文字列の終わりの終了null値を含む、コマンドラインあたりの文字数。許容される最大値はシステムによって異なり、execのパラメータ長制限から環境サイズ、2048バイトの余白を引いたものとして計算されます。値が128KiBより大きい場合、128KiBがデフォルトとして使用されます。それ以外の場合、デフォルトは最大値です。

これは、単一の呼び出しで渡すことができるファイル名の数を制限しますwc。これは、多数のファイルに対してwc複数の呼び出しが発生し、各呼び出しが入力の1つのパーティションで機能する理由を説明します。

関連情報