[A-Z]
In bash
Übereinstimmungen werden alle Sortierelemente (Zeichen, aber auch Zeichenfolgen wie Dsz
in ungarischen Gebietsschemata) angezeigt, die nach A
und vor sortieren Z
. Sortiert in Ihrem Gebietsschema c
wahrscheinlich zwischen B und C.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
So c
oder so z
würde es passen [A-Z]
, aber nicht Ẑ
oder a
.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ |
pipe> bash -c 'while IFS= read -r x; do case $x in [A-Z]) echo "$x"; esac; done'
A
á
b
B
c
C
Ç
z
Z
In der Ländereinstellung C wäre die Reihenfolge:
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
So [A-Z]
würde passen A
, B
, C
, Z
, aber nicht Ç
und noch nicht Ẑ
.
Wenn Sie in Großbuchstaben (in einem Skript) übereinstimmen möchten, können Sie [[:upper:]]
stattdessen verwenden. Es gibt keinen eingebauten Weg, bash
um nur Großbuchstaben in der lateinischen Schrift abzugleichen (außer indem sie einzeln aufgelistet werden ).
Wenn Sie das übereinstimmen soll A
auf Z
Englisch Buchstaben ohne diakritische Zeichen, können Sie entweder [A-Z]
oder [[:upper:]]
aber in der C
locale (die Daten unter der Annahme nicht in Zeichensätze wie BIG5 oder GB18030 codiert , die mehrere Zeichen , deren Codierung hat enthält die Kodierung dieser Briefe) oder Liste sie einzeln ( [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
).
Beachten Sie, dass zwischen den Schalen einige Unterschiede bestehen.
Für zsh
, bash -O globasciiranges
(seltsam benannte Option in bash-4.3 eingeführt), schily-sh
und yash
, [A-Z]
Ergebnisse auf dem aktuelle Zeichen Punkt , dessen Code zwischen dem von A
und der Z
würde so sein , entspricht das Verhalten bash
in der C - locale.
Für Asche, MKSH und alte Muscheln, wie zsh
oben, jedoch auf Einzelbyte-Zeichensätze beschränkt. Das heißt, in einem UTF-8-Gebietsschema [É-Ź]
würde dies beispielsweise nicht mit "on" übereinstimmen Ó
, aber da dies so ist [<c3><89>-<c5><b9>]
, würde dies mit den Bytewerten 0x89 bis 0xc5 übereinstimmen!
ksh93
Verhalten wie mit der bash
Ausnahme, dass es als Sonderfallbereiche behandelt wird, deren Enden beide mit Kleinbuchstaben oder Großbuchstaben beginnen. In diesem Fall werden nur Sortierelemente berücksichtigt, die zwischen diesen Enden sortiert sind, bei denen es sich jedoch (oder bei Sortierelementen mit mehreren Zeichen um das erste Zeichen) auch um Kleinbuchstaben (bzw. Großbuchstaben) handelt. So [A-Z]
würde es passen auf É
, aber nicht auf e
so e
tut Art zwischen A
und Z
ist aber nicht groß geschrieben wie A
und Z
.
Bei fnmatch()
Mustern (wie in find -name '[A-Z]'
) oder regulären Systemausdrücken (wie in grep '[A-Z]'
) hängt dies vom System und der Ländereinstellung ab. Zum Beispiel [A-Z]
stimmt auf einem GNU-System hier nicht x
das en_GB.UTF-8
Gebietsschema überein , sondern das Gebietsschema th_TH.UTF-8
. Es ist mir unklar, welche Informationen verwendet werden, um dies festzustellen, aber es basiert anscheinend auf einer Nachschlagetabelle, die aus den Gebietsschemadaten von LC_COLLATE abgeleitet wurde .
Alle Verhaltensweisen werden von POSIX zugelassen, da POSIX das Verhalten von Bereichen in anderen Gebietsschemas als dem C-Gebietsschema nicht angibt. Jetzt können wir über die Vorteile jedes Ansatzes streiten.
bash
Der Ansatz von ist sehr sinnvoll, da [C-G]
wir die Zeichen zwischen C
und haben wollen G
. Und die Sortierreihenfolge des Benutzers zu verwenden, um zu bestimmen, was dazwischen liegt, ist der logischste Ansatz.
Das Problem ist nun, dass es die Erwartungen vieler Menschen verletzt, insbesondere derjenigen, die an das traditionelle Verhalten vor Unicode gewöhnt sind, sogar an Tage vor der Internationalisierung. Während von einem normalen Benutzer, kann es sinnvoll ist , das [C-I]
umfasst h
der als h
Brief zwischen C
und I
und das [A-g]
beinhaltet nicht Z
, dann ist es eine andere Sache für die Menschen seit Jahrzehnten nur mit ASCII behandelt zu haben.
Dieses bash
Verhalten unterscheidet sich auch von der [A-Z]
Bereichsübereinstimmung in anderen GNU-Werkzeugen wie in regulären GNU-Ausdrücken (wie in grep
/ sed
...) oder fnmatch()
in find -name
.
Dies bedeutet auch, dass die [A-Z]
Übereinstimmungen mit der Umgebung, dem Betriebssystem und der Version des Betriebssystems variieren. Die Tatsache, dass [A-Z]
Á, aber nicht matches übereinstimmt, ist ebenfalls suboptimal.
Für zsh
/ verwenden yash
wir eine andere Sortierreihenfolge. Anstatt sich auf die Zeichenreihenfolge des Benutzers zu verlassen, verwenden wir die Zeichenpunktcodewerte. Das hat den Vorteil, dass es leicht zu verstehen ist, aber außerhalb von ASCII ist es aus praktischer Sicht nicht sehr nützlich. [A-Z]
Entspricht den 26 US-englischen Großbuchstaben und den [0-9]
Dezimalstellen. Es gibt Codepunkte in Unicode, die der Reihenfolge einiger Alphabete folgen, aber nicht verallgemeinert sind und nicht verallgemeinert werden können, da sich verschiedene Personen, die dasselbe Skript verwenden, nicht notwendigerweise auf die Reihenfolge der Buchstaben einigen.
Bei traditionellen Shells und mksh, dash, ist es defekt (da die meisten Leute jetzt Multi-Byte-Zeichen verwenden), aber vor allem, weil sie noch keine Multi-Byte-Unterstützung haben. Das Hinzufügen von Multi-Byte-Unterstützung zu Shells wie bash
und zsh
war eine enorme Anstrengung und dauert noch an. yash
(eine japanische Shell) wurde ursprünglich von Anfang an mit Multi-Byte-Unterstützung entwickelt.
Der Ansatz von ksh93 hat den Vorteil, dass er mit den regulären Ausdrücken oder fnmatch () des Systems konsistent ist (oder zumindest auf GNU-Systemen zu sein scheint). Dort wird die Erwartungshaltung einiger Leute nicht verletzt, da [A-Z]
Kleinbuchstaben, [A-Z]
Includes É
(und Á, aber nicht Ź) nicht enthalten sind. Es ist nicht konsistent mit sort
oder allgemeiner strcoll()
Ordnung.
locale
ausgegeben? Ich kann das nicht reproduzieren (touch foo; echo [A-Z]*
gibt das wörtliche Muster, nicht "foo", in einem ansonsten leeren Verzeichnis aus).