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 ファイルのマッチング第二拡張正規表現、大文字、小文字私無感覚に。