回答:
まず、nitpick:a*
通常のシェル構文のような文字列は、正規表現とは異なる働きをするグロブです。
高レベルの概要では、シェルインタープリター(bashなど)は、文字列a*
を、patternに一致するすべてのファイル名のリストに展開しますa*
。これらは、コマンドラインパラメータの一部になり、の単一のインスタンスになりますgrep
(プログラマーの場合、展開されたすべての単語は個別の文字列としてのargv
引数に入れられますmain
)。grep
その後、その単一のコマンドが選択した方法で引数を解析し、grep
それらの引数をファイル名、オプション、オプション引数、正規表現などとして解釈し、適切なアクションを実行します。すべてが順番に発生します(AFAIKのgrep
実装では複数のスレッドを使用していません)。
シェルスクリプトにループを実装して同じことを行う場合、以下の理由により、上記のプロセスよりも遅くなることがほぼ保証されています。ファイルごとに新しいgrepプロセスを生成すると、プロセス作成のオーバーヘッドが不必要に増加するため、確実に遅くなります。シェルスクリプトで引数リストを自分で作成し、の単一のインスタンスを使用した場合、grep
シェルコマンドは(bashで)解釈する必要があるため、シェルで実行するすべての処理が遅くなり、コードの追加レイヤーが追加されます。コンパイル済みコードの内部で、bashがすでに高速に実行していたことを再実装するだけです。
Cで自分で書く場合、最初の段落で説明したプロセスと同等のパフォーマンスを簡単に得ることができますが、現在のgrep / bash実装よりも十分なパフォーマンス向上を達成して時間を正当化することはできません。マシン固有のパフォーマンスの最適化について調べたり、移植性を犠牲にすることなく費やしました。多分、の任意に並列化可能なバージョンを考え出すことができgrep
ますが、CPUバウンドよりもI / Oバウンドになる可能性が高いため、それでも役に立たない場合があります。Globの拡張とgrepは、ほとんどの「通常の」目的にはすでに「十分に高速」です。
zcat
とzgrep
。それらを1つずつ解凍する必要はありません
はい、それはファイルのリストに展開し、結果のリストをgrep
プログラムにフィードします。少なくともman bash
、サブセクション「パス名の展開」でそれが述べられています。
あなたが言及するように、単純なケースで拡張を使用する別の方法があります:書き込みgrep <some_string> a
、を押す前にを*
押しESCます。これにより、一致するファイルのリストがコマンドラインの右側に展開されるので、を押す前にリストに問題がないことを確認できますEnter。
質問の2番目の部分については、状況によって異なります。各ファイルでgrepを順番に実行するforループを作成する場合、grepプログラムは1回ではなく、ファイルごとに1回実行されるため、確実に遅くなります。しかし、何で心に留めておくことは重要ことは一定の存在であるということである限界、それは一般的に非常に高いですが、あなたが使用できるコマンドライン引数の拡大長さには、。それを確認するには、を試してくださいgrep adasdsadf /usr/*/*/* >/dev/null
。
ESC+*
はESC+*
ドットファイル(で始まる名前)を挿入します.
が、の展開は設定に*
依存するため、bashに*を展開させるのとまったく同じではありませんdotglob
shopt
。グロブを展開および挿入するキーシーケンスはC-x *
デフォルトであり、readlineコマンドにマッピングされますglob-expand-word
。
a*
拡張の場合は変更されないようですが、より広い範囲で重要です。
zsh
注:展開可能なパラメーター(グロブパターン、ブレース展開、コマンド置換など)でタブキーを押すだけで展開されます。
C-x
ショートカットをテストしただけで、(bashを使用して)システム上のファイルのリストを展開しません。
C-x *
ファイル名だけを行うグロブだけを実行しますが、可能なすべての補完の場合と同様に、Esc *
実際にはそれがより多くのinsert-completions
ことを実行します。つまりEsc *
、空のコマンドラインでを使用する$PATH
と、たとえば、すべての実行可能ファイルの名前がに挿入されます。
glob
は正規表現ではありません。大きな違い。