Bash「ワイルドカード」と正規表現が等しくない歴史的な理由はありますか?たとえば、Bashでは[1-2]*
1または2で始まり、その後に他のものが来るすべての項目と一致し、正規表現は[1-2]*
1と2のシーケンスのみが一致すると考えます。私のBashスクリプトとREGEX fooはどちらも弱く、これらの違いに関連する問題に頻繁に直面するので、なぜ違うのか疑問に思います。
答え1
bash
ksh
もともと、いくつかのインタラクティブ機能を備えた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 extglob
ksh globのサブセットをある程度実装しています)は機能的に正規表現と同じです。たとえば、zsh
(拡張グローバル拡張を使用)では、次のことができます。
echo a#.txt
(可能性が低い)一致をより簡単にしたい場合は、a
.than.txt
をecho (^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 ファイルのマッチング第二拡張正規表現、大文字、小文字私無感覚に。
答え2
正規言語紹介を受けるクライン1956. この重要な論文には完全な現代正規表現表記法はありませんが、A*
「繰り返し回数A
」を意味する「Kleen star」を紹介しました。次の10年間で、特にランダムな.
文字について、以前の文字がオプションであることを?
示すために、多少の標準記号がたくさん登場しました。
Bashのワイルドカード記号は、以下から派生します。glob
注文する最初から最後まで紹介Unix v11971.当時は別のプログラムでワイルドカードを実行しましたが、後でシェルに移動しました。前のコマンドは「すべての文字」と「すべての文字シーケンス」を意味するglob
必要がありました。なぜこれらの役割が選択されたのかは不明です。おそらく正規表現に触発されたようです。?
*
?
*
ワイルドカードは正規表現ほど一般的に使用することを意図しておらず、当時の正規表現はあまり一般的ではなかったので、これらの概念を統合する必要はありませんでした。最初からファイル名パターンと正規表現で、、?
が.
異なる意味を持つ構文非互換性がありました。*
bashのような最新のシェルはglobモードを拡張しますが、以前のバージョンとの互換性を維持するために徐々に進化しました。 Ksh88(1988年版)コーエンシェル)は一般的な正規表現構文とは異なりますが、*(PATTERN)
繰り返し回数を表すものPATTERN
、@(PATTERN1|PATTERN2)
「PATTERN1
またはPATTERN2
」などを表すものなどから大きくインスピレーションを受けたシェルパターンの拡張構文を紹介します。
最新バージョンのbash(2.02以降)は、コマンドを最初に実行するとksh88の拡張モードをサポートしますshopt -s extglob
。
答え3
歴史的な理由:はい。引用:
http://en.wikipedia.org/wiki/Glob_(プログラミング)#Origin
違いを示すために、次は素晴らしいと簡単な例です。a*
- シェルワイルドカード: 最初の文字は で、
a
次は任意の文字 (a、ab、abca...) です。 - 正規表現:文字が0回以上繰り返されることを意味します
a
(a、aa、aaa...)。
私はこの意味の違いが新しいユーザーにとって非常に混乱していることに簡単に同意します。
ワイルドカードは初心者に慣れやすくなりますが、強力ではありません。