Bash Globbing nicht wie erwartet


8

Dies ist eine Hausaufgabenfrage:

Ordnen Sie allen Dateinamen 2 oder mehr Zeichen zu, die mit einem Kleinbuchstaben beginnen, aber nicht mit einem Großbuchstaben enden.

Ich verstehe nicht, warum meine Lösung nicht funktioniert.

Also habe ich folgendes ausgeführt:

touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax

ls [a-z]*[!A-Z]

Ausgabe:

aa  ha

Meine Frage: Warum stimmte es nicht mit "ah", "hh" oder "a123e" überein?


Funktioniert für mich richtig unter der mkshSchale, aber nicht bash --posix, also muss es eine spezielle Regel für Bash geben
— Sergiy Kolodyazhnyy

@Serg, beachten Sie, dass das Verhalten für [AZ] von POSIX nur im Gebietsschema C angegeben wird. mkshwie zsh's [A-Z]passt Ézum Beispiel nicht auf . Die [A-Z]Übereinstimmungen von ksh93 sind aktiviert, Éaber nicht aktiviert h.
— Stéphane Chazelas

Antworten:


9

Dies ist ein Problem mit dem Gebietsschema . Erweitert in Ihrem Gebietsschema [A-Z]auf etwas wie [AbBcZ...zZ](und wahrscheinlich auch auf andere wie Zeichen mit Akzent) und [^A-Z]bedeutet daher ain Ihrem Beispiel (und nur in Ihrem Beispiel) "Dateien, die mit " enden .

Wenn Sie eine solche Überraschung vermeiden möchten, müssen Sie eine Möglichkeit festlegen, LC_COLLATE=C da die Sortierung der Teil Ihrer Gebietsschemaeinstellungen ist, der für die Sortierreihenfolge verantwortlich ist. Auch leer, LC_ALLwenn es gesetzt ist, da es Vorrang haben würde.

$ ls [a-z]*[^A-Z]
aa  ha

$ ( LC_ALL=; LC_COLLATE=C; ls [a-z]*[^A-Z] )
a123e  aa  ah  ha  hh

Oder, besser, es ist wahrscheinlich vorzuziehen, die Gebietsschemaeinstellungen nicht zu ändern und die entsprechenden Klassen zu verwenden: [:lower:]anstelle von [a-z]und [:upper:]anstelle von [A-Z].

$ ls [[:lower:]]*[^[:upper:]]
a123e  aa  ah  ha  hh

Oder verwenden Sie die globasciirangesOption von bash :

$ shopt -s globasciiranges
$ ls [a-z]*[^A-Z]
a123e  aa  ah  ha  hh

$ shopt -u globasciiranges
$ ls [a-z]*[^A-Z]
aa  ha

@heemayl, no LC_ALL=C ls [a-z]*[^A-Z]würde nur das lsGebietsschema beeinflussen, nicht das Gebietsschema, das von der Shell verwendet wird, um den Glob zu erweitern oder diese Befehlszeile zu analysieren.
— Stéphane Chazelas

Sie müssen nicht exportieren, LC_xxxdamit es auf den Glob angewendet wird, aber es wäre vorzuziehen, damit ls das gleiche Gebietsschema erhält.
— Stéphane Chazelas

1
Beachten Sie, dass in einer Gegend , in der charset ist GB18030 zum Beispiel mit der LC_ALL = C Ansatz wäre es nicht auf einer Datei mit dem Namen Übereinstimmen test-鏏zum Beispiel , weil , sobald Sie das charset zu dem dem C locale ändern, 鏏wird <0xe7>A. IOW, wenn Sie LC_CTYPE ändern, erhalten Sie unterschiedliche Zeichen.
— Stéphane Chazelas

1
Beachten Sie, dass ich vermute, dass [AZ] im Gebietsschema des OP mehr als AbBcC ... zZ abdeckt. Wahrscheinlich hat auch é, Á(aber wahrscheinlich nicht Ź). IOW [A-Z]macht die Verwendung außerhalb des Gebietsschemas C wenig Sinn.
— Stéphane Chazelas

@ StéphaneChazelas Vielen Dank für Ihr hervorragendes Feedback. Antwort aktualisiert. Ich glaube, ich habe alles berücksichtigt.
— Xhienne
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.