[A-Z]inは、後にソートされ、前にソートされるbashすべての照合要素(文字ですがDsz、ハンガリー語ロケールのように呼び出しも文字のシーケンス)に一致します。ロケールでは、おそらくBとCの間でソートされます。AZc
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
そうcかzによってマッチされるだろう[A-Z]が、ありませんẐかa。
$ printf '%s\n' A a á b B c C Ç z Z Ẑ |
pipe> bash -c 'while IFS= read -r x; do case $x in [A-Z]) echo "$x"; esac; done'
A
á
b
B
c
C
Ç
z
Z
Cロケールでは、順序は次のようになります。
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
だから、[A-Z]マッチするA、B、C、Z、ではなくÇ、まだありませんẐ。
(すべてのスクリプトで)大文字で一致させたい場合は、[[:upper:]]代わりに使用できます。ラテンbash文字の大文字のみを照合する組み込みの方法はありません(個別にリストする場合を除く)。
あなたが一致する場合AにZ 、英語の発音区別符号なし文字を、あなたはどちらかを使用することができます[A-Z]か[[:upper:]]が、中Cロケール(データを仮定することは、いくつかの文字エンコーディングがあるBIG5またはGB18030などの文字セットでエンコードされていない含まれていたり、リスト、それらの文字のエンコーディング)それらを個別に([ABCDEFGHIJKLMNOPQRSTUVWXYZ])。
シェルには多少の違いがあることに注意してください。
(奇妙という名前のbash-4.3で導入されたオプション)、および、コードポイントの間にある文字に一致していることをとのことなので、の動作に相当しますCロケールインチzshbash -O globasciirangesschily-shyash[A-Z]AZbash
ash、mksh、および古代シェルの場合、zsh上記と同じですが、シングルバイト文字セットに制限されています。つまり、たとえばUTF-8ロケールでは[É-Ź]on Óに一致しませんが[<c3><89>-<c5><b9>]、それはなので、バイト値0x89から0xc5に一致します!
ksh93bash両端が小文字または大文字で始まる特別な場合の範囲として扱うことを除いて、同様に動作します。その場合、それらの端の間でソートする照合要素でのみ一致しますが、それは(または複数文字照合要素の最初の文字)小文字(または大文字)でもあります。だから、[A-Z]そこにマッチしますÉが、ないのeとeの間でソートしAやZけどのように大文字されていないAとZ。
ためのfnmatch()パターン(のようなfind -name '[A-Z]')、またはシステムの正規表現(のようにgrep '[A-Z]')、それはシステムおよびロケールに依存します。たとえば、ここのGNUシステムでは、ロケールで[A-Z]は一致しませんxが、en_GB.UTF-8ロケールでは一致しますth_TH.UTF-8。それを判断するためにどの情報を使用するかはわかりませんが、明らかにLC_COLLATEロケールデータから派生したルックアップテーブルに基づいています)。
POSIXではCロケール以外のロケールでは範囲の動作が指定されていないため、POSIXではすべての動作が許可されます。これで、各アプローチの利点について議論できます。
bashアプローチは、のように多くの意味になり[C-G]、我々は間に文字をしたい、CとG。そして、何が中間にあるかを決定するためにユーザーのソート順を使用することが最も論理的なアプローチです。
現在、問題は多くの人々、特にUnicode以前、国際化以前の伝統的な振る舞いに慣れている人々の期待を破ることです。通常のユーザーからは、文字がからの間であり、を[C-I]含まないことを含むことは理にかなっているかもしれませんが、ASCIIを数十年しか扱っていない人にとっては別の問題です。hhCI[A-g]Z
そのbash行動も異なっている[A-Z](のようにGNU正規表現のように他のGNUツールで範囲マッチングgrep/ sed...)かfnmatch()のようにfind -name。
また、[A-Z]一致するものは、環境、OS、およびOSのバージョンによって異なることを意味します。[A-Z]Áに一致するがnotに一致しないという事実も最適ではありません。
以下のためにzsh/ yash、我々は異なるソート順を使用します。ユーザーの文字順序の概念に依存する代わりに、文字ポイントコード値を使用します。これには理解しやすいという利点がありますが、ASCII以外の実用的な点ではあまり有用ではありません。[A-Z]26個の米国英語の大文字と[0-9]一致し、10進数の数字と一致します。Unicodeにはいくつかのアルファベットの順序に従うコードポイントがありますが、一般化されておらず、同じスクリプトを使用する別の人が必ずしも文字の順序に同意しないため、一般化できません。
従来のシェルとmksh、ダッシュの場合、壊れています(今ではほとんどの人がマルチバイト文字を使用しています)が、主にマルチバイトサポートがまだないためです。bashやなどのシェルにマルチバイトサポートを追加するzshことは大きな努力であり、現在も進行中です。yash(日本語のシェル)は当初、最初からマルチバイトをサポートするように設計されていました。
ksh93のアプローチには、システムの正規表現またはfnmatch()(または少なくともGNUシステムでは少なくとも表示される)と一貫性があるという利点があります。そこでは、[A-Z]小文字、[A-Z]インクルードÉ(およびÁではなくŹ)が含まれていないため、一部の人々の期待に反しません。それは一貫していないsortか、一般的にstrcoll()順序ではありません。
locale出力は何ですか?これを再現することはできません(touch foo; echo [A-Z]*「foo」ではなくリテラルパターンを出力します)。