Ich benutze Bash unter Linux. Die folgende if-Anweisung ist erfolgreich, aber sollte sie nicht einen Fehlercode zurückgeben?
if [[ ■ = [⅕⅖⅗] ]] ; then echo yes ; fi
Das Quadrat entspricht NICHT einem der Zeichen, daher verstehe ich nicht, warum ich einen Erfolgscode erhalte.
Es ist mir wichtig, die doppelten Klammern in meinem Fall zu behalten.
Gibt es in diesem Szenario eine andere Möglichkeit, einen Bereich festzulegen, oder welche anderen Vorschläge?
C
nicht, da es sich nicht um Einzelbyte-Zeichen handelt.C.UTF-8
würde tun, wo verfügbar.Antworten:
Dies ist eine Folge davon, dass diese Zeichen die gleiche Sortierreihenfolge haben.
Das werden Sie auch bemerken
gibt nur eine Zeile zurück.
Oder das:
Gibt true zurück (wie von POSIX verlangt).
Die meisten mit GNU-Systemen gelieferten Gebietsschemas haben eine Anzahl von Zeichen (und sogar Folgen von Zeichen (Sortierfolgen)), die dieselbe Sortierreihenfolge haben. Bei diesen ist die Reihenfolge nicht definiert, und Zeichen, deren Reihenfolge nicht definiert ist, haben in GNU-Systemen dieselbe Sortierreihenfolge. Es gibt Zeichen, die explizit so definiert sind, dass sie die gleiche Sortierreihenfolge wie Ș und Ş haben (obwohl es (für mich jedenfalls) keine wirkliche Logik oder Konsistenz darüber gibt, wie es gemacht wird).
Das ist die Quelle ziemlich überraschender und falscher Verhaltensweisen. Ich habe das Problem vor kurzem in der Mailingliste der Austin-Gruppe (der Stelle hinter POSIX und der Single UNIX Specification) angesprochen, und die Diskussion ist ab dem 03.04.2015 noch nicht abgeschlossen.
In diesem Fall ist mir unklar , ob wo und nach welcher Sortierung
[y]
übereinstimmen soll. Da jedoch ein Klammerausdruck mit einem Sortierelement übereinstimmen soll, lässt dies darauf schließen, dass das Verhalten erwartet wird.x
x
y
bash
In jedem Fall denke ich,
[⅕-⅕]
oder[⅕-⅖]
sollte zumindest übereinstimmen■
.Sie werden feststellen, dass sich verschiedene Tools unterschiedlich verhalten. ksh93 verhält sich wie
bash
GNUgrep
odersed
nicht. Einige andere Muscheln haben ein anderes Verhalten, andere mögenyash
noch buggyiger sein.Für ein konsistentes Verhalten benötigen Sie ein Gebietsschema, in dem alle Zeichen unterschiedlich sortiert sind. Das Gebietsschema C ist das typische. Bei den meisten Systemen ist der Zeichensatz in der Ländereinstellung C jedoch ASCII. Auf GNU-Systemen haben Sie im Allgemeinen Zugriff auf ein
C.UTF-8
Gebietsschema, mit dem Sie stattdessen UTF-8-Zeichen bearbeiten können.So:
oder das Standardäquivalent:
sollte false zurückgeben.
Eine andere Alternative wäre, nur
LC_COLLATE
auf C zu setzen , was auf GNU-Systemen funktionieren würde, aber nicht unbedingt auf anderen, bei denen es fehlschlagen könnte, die Sortierreihenfolge von Mehrbyte-Zeichen anzugeben.Eine Lehre daraus ist, dass Gleichheit keine so klare Vorstellung ist, wie man es beim Vergleichen von Strings erwarten würde. Gleichheit könnte bedeuten, von streng bis am wenigsten streng.
Für 2 oder 3 wird davon ausgegangen, dass beide Zeichenfolgen gültige Zeichen enthalten. In UTF-8 und einigen anderen Codierungen bilden einige Bytefolgen keine gültigen Zeichen.
1 und 2 sind deshalb nicht unbedingt gleichwertig, oder weil einige Zeichen möglicherweise mehr als eine mögliche Kodierung haben. Dies ist in der Regel der Fall bei statusbehafteten Codierungen wie ISO-2022-JP, bei denen
A
entweder41
oder ausgedrückt werden kann1b 28 42 41
(1b 28 42
die Reihenfolge, in der auf ASCII umgeschaltet wird, und Sie können so viele davon einfügen, wie Sie möchten, was keinen Unterschied macht), obwohl ich Ich würde nicht erwarten, dass diese Codierungstypen immer noch verwendet werden, und GNU-Tools funktionieren zumindest im Allgemeinen nicht richtig mit ihnen.Beachten Sie auch, dass die meisten Nicht-GNU-Dienstprogramme den 0-Byte-Wert (das NUL-Zeichen in ASCII) nicht verarbeiten können.
Welche dieser Definitionen verwendet wird, hängt vom Dienstprogramm und der Implementierung oder Version des Dienstprogramms ab. POSIX ist diesbezüglich nicht 100% klar. In der Ländereinstellung C sind alle 3 gleichwertig. Außerhalb dieser YMMV.
quelle
é
undé
zu sein, aber nichte
. POSIXs Begriff der Sortierreihenfolge ist selten richtig, basiert zu stark auf Zeichen und berücksichtigt nicht die gebräuchlichsten Arten der Sortierung von Zeichenfolgen (z. B. verwenden französische Wörterbücher keine lexikografische Reihenfolge zum Sortieren von Wörtern: Sie führen eine erste lexikografische Übergabe mit ignorierten und hervorgehobenen Akzenten durch Verwenden Sie dann Akzente, um die Krawatten zu entscheiden.Du machst es falsch
=
und==
bist nicht dasselbe.Probieren Sie diese Beispiele aus:
quelle
=
zur Überprüfung der Gleichheit verwendet werden soll. Das Problem sind die fehlenden Anführungszeichen, nicht der Operator.man bash
sagt im[[
Abschnitt: „Der Operator = entspricht ==.“[[...]]
Operator nicht an. Und = und == sind in den Shells, in denen sie implementiert wurden (ksh / bash / zsh) und für den Mustervergleich nicht gleich.