シェル(例:bash)はワイルドカードパターンをどのように拡張しますか?

シェル(例:bash)はワイルドカードパターンをどのように拡張しますか?

ディレクトリに文字 "a"で始まる100個のファイルがあるとします。

grep <some string> a*端末で実行すると、シェルはこれをどのように処理しますか?

正規表現を展開し、aで始まるすべてのファイルのリストを取得し、各ファイルを順番にgrepしますか?それとも別の方法がありますか?

上記の「a」で始まるファイル名の配列があるとしましょう。 forループを作成してシェルスクリプトまたはacプログラムで直接反復を実行すると、時間がかかりませんか?

ベストアンサー1

a*まず、少し問題です。一般的なシェル構文などの文字列は、正規表現とは異なる動作をするglobです。

通常、シェルインタプリタ(bashなど)は、文字列をパターンにa*一致する各ファイル名のリストに展開しますa*。これはコマンドライン引数の一部になります。一つ(プログラマの場合、grepすべての拡張語は別々の文字列引数として提供されますargvmain。その後、コマンドはgrep選択した方法で引数を解析し、grepそれをファイル名、オプション、オプションパラメータ、正規表現などとして解釈し、適切なアクションを実行します。すべてが順次発生します(私が知る限り、マルチスレッドを使用した実装はありませんgrep)。

同じタスクを実行するためにシェルスクリプトでループを実装した場合、次の理由で上記のプロセスよりもほぼ遅くなります。各ファイルに対して新しいgrepプロセスを作成すると、不要なプロセス生成のオーバーヘッドが確実に遅くなります。シェルスクリプトから直接引数リストを作成して単一のgrepインスタンスを使用する場合は、シェルコマンドを(bashを介して)解釈する必要があり、追加のコードレイヤが追加されるため、シェルで実行するすべての操作はまだ遅くなります。そして、コンパイルされたコードでbashが内部的に速くすることを再実装するだけです。

Cで直接書くと、最初の段落で説明したプロセスと同様のパフォーマンスを簡単に得ることができますが、特定の最適化を探索しなくても時間を正当化するのに十分なパフォーマンスを向上させる可能性は低くなります。機械性能でなければ、移植性が犠牲になる。たぶんランダムに並列化できるバージョンを作成しようとするかもしれませんが、grepCPUバインディングよりもI / Oバインディングに依存しているので、それは役に立ちません。グローバル拡張とgrepは、ほとんどの「一般的な」用途には「十分に高速です」。

おすすめ記事