In allen Shells, die mir bekannt sind, rm [A-Z]*
entfernt alle Dateien, die mit einem Großbuchstaben beginnen, aber mit bash entfernt dies alle Dateien, die mit einem Buchstaben beginnen.
Da dieses Problem unter Linux und Solaris mit bash-3 und bash-4 besteht, kann es sich nicht um einen Fehler handeln, der durch einen fehlerhaften Musterabgleich in libc oder eine falsch konfigurierte Locale-Definition verursacht wird.
Ist dieses seltsame und riskante Verhalten beabsichtigt oder ist dies nur ein Fehler, der seit vielen Jahren nicht behoben wird?
Akzeptierte Antwort:
Beachten Sie, dass bei der Verwendung von Bereichsausdrücken wie [a-z] je nach Einstellung von LC_COLLATE.
Buchstaben des anderen Falls enthalten sein können
LC_COLLATE
ist eine Variable, die die beim Sortieren der Ergebnisse der Pfadnamenerweiterung verwendete Sortierreihenfolge bestimmt und das Verhalten von Bereichsausdrücken, Äquivalenzklassen und Sortierfolgen innerhalb der Pfadnamenerweiterung und des Musterabgleichs bestimmt.
Beachten Sie Folgendes:
$ 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
Beachten Sie, wenn der Befehl echo [a-z]
aufgerufen wird, wäre die erwartete Ausgabe alle Dateien mit Kleinbuchstaben. Auch mit echo [A-Z]
, werden Dateien mit Großbuchstaben erwartet.
Standardsortierungen mit Gebietsschemas wie en_US
haben die folgende Reihenfolge:
aAbBcC...xXyYzZ
- Zwischen
a
undz
(in[a-z]
) sind ALLE Großbuchstaben, außerZ
. - Zwischen
A
undZ
(in[A-Z]
) sind ALLE Kleinbuchstaben, außera
.
Siehe:
aAbBcC[...]xXyYzZ
| |
from a to z
aAbBcC[...]xXyYzZ
| |
from A to Z
Wenn Sie den LC_COLLATE
ändern Variable zu C
es sieht wie erwartet aus:
$ export LC_COLLATE=C
$ echo [a-z]
a b c x y z
$ echo [A-Z]
A B C X Y Z
Es ist also kein Fehler , es handelt sich um ein Sortierproblem .
Anstelle von Bereichsausdrücken können Sie POSIX-definierte Zeichenklassen wie upper
verwenden oder lower
. Sie funktionieren auch mit anderen LC_COLLATE
Konfigurationen und sogar mit Zeichen mit Akzent :
$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z