GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum stimmt [a-z] mit Kleinbuchstaben in Bash überein?

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 und z (in [a-z] ) sind ALLE Großbuchstaben, außer Z .
  • Zwischen A und Z (in [A-Z] ) sind ALLE Kleinbuchstaben, außer a .

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

Linux
  1. Was macht „exec {fd}/watchdog“ in Bash?

  2. Warum ignoriert Sudo Aliasse?

  3. Warum kann ich Cd nicht in einem Bash-Skript verwenden?

  4. Warum funktioniert die Regex in Bash nur, wenn es sich um eine Variable handelt und nicht direkt?

  5. Bash:Warum wird das übergeordnete Skript nicht bei SIGINT beendet, wenn das untergeordnete Skript SIGINT abfängt?

Was macht 'bash -c'?

Der Musterabgleich funktioniert nicht im Bash-Skript

Warum funktioniert Bash `(())` nicht innerhalb von `[[]]`?

Warum wird mein $LD_LIBRARY_PATH zurückgesetzt, wenn ich screen mit bash verwende?

Wie testet Bash 'false'?

Warum reicht das Löschen des Bash-Verlaufs nicht aus?