[AZ]がbashの小文字と一致するのはなぜですか?

[AZ]がbashの小文字と一致するのはなぜですか?

私が知っているすべてのシェルではrm [A-Z]*大文字で始まるすべてのファイルが削除されますが、bashでは大文字で始まるすべてのファイルが削除されます。

この問題はbash-3とbash-4を使用してLinuxとSolarisに存在するため、libcの不良パターンマッチングや誤って設定されたロケール定義によって発生したバグである可能性はありません。

この奇妙で危険な行動は意図的なものですか、それとも長年にわたって存在してきた修正されていないバグですか?

ベストアンサー1

[az]などの範囲表現を使用している場合は、LC_COLLATE設定によって他の大文字と小文字を含めることができることに注意してください。

LC_COLLATEパス名拡張結果をソートするときに使用される照合順序を決定し、パス名拡張とパターンマッチングの範囲式、等価クラス、およびソート順序の動作を決定する変数。


以下を考慮してください。

$ touch a A b B c C x X y Y z Z
$ ls
a  A  b  B  c  C  x  X  y  Y  z  Z
$ echo [a-z] # Note the missing uppercase "Z"
a A b B c C x X y Y z
$ echo [A-Z] # Note the missing lowercase "a"
A b B c C x X y Y z Z

このコマンドを呼び出すときにecho [a-z]予想される出力は、すべて小文字のファイルです。また、echo [A-Z]ファイルには大文字も含める必要があります。


ロケールとの標準照合順序en_USは次のとおりです。

aAbBcC...xXyYzZ
  • aを除くすべての大文字は、z(in)の間にあります。[a-z]Z
  • AおよびZ(in)[A-Z]はを除いてすべて小文字ですa

望むより:

     aAbBcC[...]xXyYzZ
     |              |
from a      to      z

     aAbBcC[...]xXyYzZ
      |              |
from  A     to       Z

LC_COLLATE変数を変更すると、期待Cどおりに見えます。

$ export LC_COLLATE=C
$ echo [a-z]
a b c x y z
$ echo [A-Z]
A B C X Y Z

だからそうです間違いではありません、それ問題の整理


範囲式の代わりに POSIX 定義の範囲式を使用できます。キャラクタークラスupperまたはlower。また、さまざまな構成で動作し、LC_COLLATE使用することもできます。アクセント文字:

$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z

おすすめ記事