私が知っているすべてのシェルで、rm [A-Z]*
大文字で始まるすべてのファイルを削除しますが、bashを使用すると、文字で始まるすべてのファイルが削除されます。
この問題はbash-3とbash-4を使用するLinuxとSolarisに存在するため、libcのバグのあるパターンマッチャーやロケール定義の設定ミスが原因のバグではありません。
この奇妙で危険な行動は意図されたものですか、それともこれは何年もの間修正されていない状態で存在する単なるバグですか?
承認された回答:
[a-z]のような範囲式を使用する場合、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
([a-z]
)は、Z
を除くすべて大文字です。 。 -
A
の間 およびZ
([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
つまり、バグではありません 、これは照合の問題です 。
範囲式の代わりに、upper
などのPOSIX定義の文字クラスを使用できます。 またはlower
。さまざまなLC_COLLATE
でも機能します 構成、さらにはアクセント付きの文字 :
$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z