Bashのワイルドカードの歴史

Bashのワイルドカードの歴史

Bash「ワイルドカード」と正規表現が等しくない歴史的な理由はありますか?たとえば、Bashでは[1-2]*1または2で始まり、その後に他のものが来るすべての項目と一致し、正規表現は[1-2]*1と2のシーケンスのみが一致すると考えます。私のBashスクリプトとREGEX fooはどちらも弱く、これらの違いに関連する問題に頻繁に直面するので、なぜ違うのか疑問に思います。

ベストアンサー1

bashkshもともと、いくつかのインタラクティブ機能を備えたcsh / tcshの部分複製で、1980年代後半に設計されました。

ワイルドカードのソースは、対応するワイルドカードが組み込まれた初期シェルで見つける必要があります。

kshそれ自体はBourneシェルの拡張です。 Bourneシェル自体(1979年にUnix V7で最初にリリースされました)は最初からきちんと実装されましたが、Thompsonシェル(V1 - > V6シェル)から完全に外れることなくMasheyシェルの機能をマージします。

具体的には、コマンドパラメータはまだ空白で区切られており、|新しいパイプ演算子が^まだ代替としてサポートされています([!a-z]これを実行して実行しない理由についての説明もあります[^a-z])。$1スクリプトの最初のパラメータとその逆スラッシュはまだエスケープ文字です。多くの正規表現演算子(^\|$)はシェルで固有の特別な意味を持ちます。

Thompsonシェルは、ワイルドカードを指定するために外部ユーティリティを使用します。sh引用符がない*、またはsがコマンドで見つかった場合は、[そのコマンドが実行されます。?glob

rm *.txt

最終的には次のようにglobを実行します。

["glob", "rm", "*.txt"]

glob は最終的にrmパターンと一致するファイルのリストを通して実行されます。

grep a.\*b *.txt

次のように実行されますglob

["glob", "grep", "a.\252b", "*.txt"]

*glob上記は、文字がワイルドカードとして処理されるのを防ぐために文字にビット8を設定することによって引用されました。globこのビットは通話前に削除されますgrep

正規表現を使って同じことをするには:

regexp rm '\.txt$'

または:

regexp rm '^[^.].*\.txt$'

ドットファイルを除外します。

エスケープ演算子はシェル特殊文字としても使用されるため、必要であり、正規表現演算子がファイル名.に一般的に使用されるため、一致するファイル名は初心者にとってあまり適さず複雑になります。ほとんどの場合、必要なものワイルドカード?1()または任意の数字()文字を置き換えることができます*

別のシェルは別のワイルドカード文字を追加します。今日、kshおよびzsh glob(bash -O extglobksh globのサブセットをある程度実装しています)は機能的に正規表現と同じです。たとえば、zsh(拡張グローバル拡張を使用)では、次のことができます。

echo a#.txt

(可能性が低い)一致をより簡単にしたい場合は、a.than.txtecho (^a*\.txt$)使用してください(ここで中括弧はシェル演算子から正規表現演算子を分離する方法として使用されます。これはおそらくシェルで処理する方法です)。

echo (foo|bar|<1-20>).(#i)mpg

デフォルト名がfoo、bar、または1〜20の10進数(大文字と小文字を区別しない)のmpgファイルの場合...

ksh93正規表現(基本、拡張、Perlのような、または「改善された」)をglobに統合することも可能です(バグが多いが)、globとregexp(printf %R、、printf %P)の間を変換するためのツールもあります。

echo ~(Ei:.*\.txt)

(非表示) txt ファイルのマッチング第二拡張正規表現、大文字、小文字無感覚に。

おすすめ記事