次の場所にある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
。 (詳しくは、この場合、呼び出すと、必要cat
なfind
回数に関係なく実行することを決定でき、実行することにしました。パイプ文字の次の部分は範囲外ですので、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つのパーティションで機能する理由を説明します。