よく分かりません:
grep -r -i 'the brown dog' /*
本当にあなたが意図したものです。これは、隠されていないすべてのファイルとディレクトリでgrepを再帰的に実行することを意味します/
(ただし、隠しファイルとそれらの内部のディレクトリはまだ見えます)。
あなたが意味すると仮定:
grep -r -i 'the brown dog' /
注意すべきいくつかの点:
- すべての
grep
実装がサポートするわけではありません-r
。そして、それらの間で動作が異なります:ディレクトリツリーを横断するときにディレクトリへのシンボリックリンクに従うものもあります(つまり、同じファイルで何度も検索したり、無限ループで実行したりする可能性があります)。一部はデバイスファイル(/dev/zero
たとえば、かなり時間がかかります)やパイプやバイナリファイルの内部を調べますが、そうでないものもあります。
grep
ファイルを発見するとすぐにファイルの内部を調べ始めるので効率的です。ただし、ファイル内を検索している間は、検索するファイルをこれ以上探していません(ほとんどの場合、おそらく同様に)
きみの:
find / -type f -exec grep -i 'the brown dog' {} \;
(-r
ここでは意味をなさないものを削除しました)は、grep
ファイルごとに1 つを実行しているため、非常に非効率的です。;
引数を1つだけ受け入れるコマンドにのみ使用してください。さらに、ここでgrep
は、1つのファイルのみを検索するため、ファイル名は出力されないため、一致する場所がわかりません。
あなたはデバイスファイル、パイプ、シンボリックリンクの内部を見ていません...、シンボリックリンクをたどっていませんが、あなたは潜在的にのようなものの中を見ているの/proc/mem
です。
find / -type f -exec grep -i 'the brown dog' {} +
grep
可能な限り少ないコマンドが実行されるため、はるかに良いでしょう。最後の実行にファイルが1つしかない場合を除き、ファイル名を取得します。そのためには、以下を使用することをお勧めします。
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
またはGNUでgrep
:
find / -type f -exec grep -Hi 'the brown dog' {} +
噛むのに十分なファイルが見つかるgrep
まで開始されないことに注意してください。そのfind
ため、初期遅延が発生します。またfind
、前のファイルgrep
が返されるまで、さらにファイルを検索し続けません。大きなファイルリストを割り当てて渡すと、(おそらく無視できるほどの)影響があるため、全体としては、grep -r
シンボリックリンクをたどったり、デバイスの内部を調べたりしない場合よりも全体的に効率が低下する可能性があります。
GNUツールの場合:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
上記のように、grep
実行されるインスタンスは可能な限り少なくfind
なりますが、最初のgrep
呼び出しが最初のバッチ内を検索している間、さらにファイルを検索し続けます。しかし、それは利点かもしれませんし、そうでないかもしれません。たとえば、回転ハードドライブにデータを保存し、ディスク上の異なる場所に保存されたデータにアクセスするfind
とgrep
、ディスクヘッドが絶えず移動するため、ディスクのスループットが低下します。RAIDのセットアップでは(どこfind
とgrep
異なるディスクにアクセスする場合があります)またはSSDの上で、それが正の違いを作るかもしれません。
RAIDセットアップでは、複数の同時 grep
呼び出しを実行することで状況が改善される場合があります。3つのディスクを備えたRAID1ストレージ上のGNUツールを引き続き使用すると、
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
パフォーマンスが大幅に向上する可能性があります。ただし、2番目のコマンドgrep
は、最初のgrep
コマンドがいっぱいになるのに十分なファイルが見つかった場合にのみ開始されることに注意してください。そのための-n
オプションを追加して、xargs
より早く実行することができます(grep
呼び出しごとに渡すファイルが少なくなります)。
またxargs
、端末デバイス以外に出力をリダイレクトする場合、greps
sは出力のバッファリングを開始することに注意してください。これは、これらgrep
のsの出力がおそらく誤ってインターリーブされることを意味します。あなたは使用する必要があるだろうstdbuf -oL
ことを回避する(あなたはまだ非常に長い行(通常> 4KiB)に問題がある場合があります)または、それぞれが別々のファイルでの出力を書き込む必要があり、それらを連結するためにそれらの上に(GNUやFreeBSD上のような利用可能な場合)最後に。
ここで、探している文字列は(正規表現ではなく)固定されているため、-F
オプションを使用すると違いが生じる可能性があります(grep
実装が既に最適化する方法を知っているとは限りません)。
大きな違いを生む可能性のあるもう1つのことは、マルチバイトロケールの場合にロケールをCに修正することです。
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
内部を参照しないようにするには/proc
、/sys
...、-xdev
検索するファイルシステムを使用して指定します。
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
または、明示的に除外するパスを整理します。
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +