Groß- und Kleinschreibung beim Globbing in eckigen Klammern


10

Normalerweise unterscheidet Bash Globbing zwischen Groß- und Kleinschreibung:

$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips

Die Verwendung eckiger Klammern scheint dies nicht zu ändern:

$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips

Es ändert sich immer noch nicht, wenn ein Bindestrich verwendet wird:

$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips

Aber die Buchstaben sind durchsetzt:

$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py

Dies deutet darauf hin, dass der Bindestrich die Gebietsschema-Reihenfolge "AaBbCcDd" verwendet. Also: Gibt es eine Möglichkeit zum Globieren für alle Dateien, die mit einem Großbuchstaben beginnen?


3
Beachten Sie auch das Gotcha, dass [AZ] mit jedem Kleinbuchstaben außer 'z' übereinstimmt!
PJTraill

Antworten:


12

In Bash-Version 4.3 und höher gibt es eine Shopt-Option namens globasciiranges:

Laut Shopt Built Gnu Manpages :

globasciiranges
Wenn diese Option aktiviert ist, verhalten sich Bereichsausdrücke, die in Klammern für Mustervergleiche verwendet werden (siehe Mustervergleich), bei Vergleichen wie im herkömmlichen C-Gebietsschema. Das heißt, die Sortierfolge des aktuellen Gebietsschemas wird nicht berücksichtigt, sodass 'b' nicht zwischen 'A' und 'B' sortiert wird und ASCII-Zeichen in Groß- und Kleinbuchstaben zusammen sortiert werden.

Als Ergebnis können Sie

$ shopt -s globasciiranges 
$ echo [A-Z]*

Verwenden Sie shopt -uzum Deaktivieren.

Eine andere Möglichkeit besteht darin, das Gebietsschema in C zu ändern. Sie können dies vorübergehend mithilfe einer Unterschale tun:

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )

Sie erhalten die gewünschten Ergebnisse, und wenn die Unter-Shell fertig ist, bleibt das Gebietsschema Ihrer Haupt-Shell unverändert.

Eine andere Alternative besteht darin [A-Z], die Klammererweiterung {A..Z}zusammen mit der nullglobOption bash shopt zu verwenden.

Durch Aktivieren der nullglobOption wird anstelle des Musters selbst eine Nullzeichenfolge zurückgegeben, wenn ein Muster während der Pfadnamenerweiterung nicht übereinstimmt.
Infolgedessen funktioniert dieser wie erwartet:

$ shopt -s nullglob;printf '%s\n' {A..Z}*

2
Perfekt danke. Ich kann es nicht verwenden, [[:upper:]]weil ich eigentlich nur einen Teil des Alphabets möchte, aber das funktioniert.
Rosuav

1
@rosuav Willkommen. Überprüfen Sie auch die Sub-Shell-Alternative.
George Vasiliou

"Wenn aktiviert gleich C-Gebietsschema ist" - meinst du, es wirkt sich auf das Gebietsschema aus, das für das Globbing verwendet wird, und auf nichts anderes? (Ein Referenzlink wäre hilfreich gewesen - das Beste , was ich finden kann, ist gnu.org/software/bash/manual/html_node/Pattern-Matching.html , aber ich hätte eine Liste aller Shell-Optionen vorgezogen, aber globasciiranges fehlt von gnu.org/software/bash/manual/html_node/… ; auch die Frage unix.stackexchange.com/questions/227070/… behandelt dieses Problem ausführlich.) Auch ab Version 4.3.
PJTraill

@PjTrail Siehe meine Bearbeitung mit einem Referenzlink zu allen Shopt-Optionen. Sie können auch man bashin Ihrem Terminal ausführen und nach /Globasciiranges suchen (mit ).
George Vasiliou

Würde LC_ALL=C printf '%s\n' [A-Z]*für Ihre zweite Lösung nicht funktionieren - ohne Subshell? Übrigens: Es gibt einen Tippfehler: nullblogAber es sind zu wenige Zeichen, als dass ich ihn korrigieren könnte.
Joe

5

Sie können alle Großbuchstaben wie folgt schreiben:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

oder use kann die benannte Zeichenklasse verwenden [:upper:], um alle Großbuchstaben in Ihrer aktuellen darzustellen locale:

[[:upper:]]*

Wie Sie bemerkt haben, werden bei Verwendung von Bereichen wie [B-C]Groß- und Kleinbuchstaben für dasselbe alphabetische Zeichen nebeneinander angeordnet (gemäß der Sortierreihenfolge von locale).


3

Das Einfügen von „nicht intuitiven“ Zeichen in Zeichenbereiche, z. B. das Einfügen von Kleinbuchstaben in einen Bereich, dessen Grenzen Großbuchstaben sind, ist auf die LC_COLLATEGebietsschemaeinstellung zurückzuführen. LC_COLLATEsoll die Sortierreihenfolge anzeigen, aber es macht einen schlechten Job (das Sortieren von Zeichenfolgen ist komplexer als das, was Gebietsschemas können) und Sie sind ohne besser dran. Ich empfehle, LC_COLLATEEinstellungen aus Ihrem Gebietsschema zu entfernen . Wenn Sie Einstellung LANG, oder LANGUAGE, das nicht tun und setzen nur die , die Sie brauchen: LC_CTYPE, LC_MESSAGES, LC_TIME.

Weitere Hintergrundinformationen zu Gebietsschemas finden Sie unter Worauf sollte ich mein Gebietsschema einstellen und welche Auswirkungen hat dies? und setze LC_ * aber nicht LC_ALL

Um zuverlässige Ergebnisse in einem Skript unabhängig von den Einstellungen des Benutzers zu erhalten, legen Sie fest LC_ALL=C.


0

Einstellen:

shopt -u nocaseglob

Von der Bash-Manpage:

>     nocaseglob
>         If  set,  bash matches filenames in a case-insensitive
>         fashion when performing pathname expansion (see Pathname
>          Expansion above).

Wenn Sie 'globasciiranges' einstellen, weiß ich nicht, was mit Nicht-ASCII-Zeichen wie utf-8 passieren wird


0

echo [cC] * sollte tun, was Sie wollen, ähnlich [A-Za-z] *

Ich bin hier , weil auf meinem System Globbing hat gerade aufgehört empfindlich Fall, so viele meine Skripte nicht mehr funktionieren , wie sie sollten :-(


Das ist das Gegenteil von dem, was ich sehe. Überprüfen Sie jedoch die anderen Antworten auf Vorschläge.
Rosuav
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.