Was ist im folgenden Code-Snippet los? Ich erhalte nicht meine erwartete Ausgabe.
Ich würde denken, dass es ein Fehler war, aber es passiert für 2 verschiedene Programme (uniq und sort), also vermute ich, dass es etwas damit zu tun hat ... nun, ich weiß nicht was ... daher die Frage.
Die ersten 3 (von 4) Beispiele funktionieren, aber das vierte schlägt fehl!.
Ich würde für alle Charaktere das gleiche Verhalten erwarten.
dh. 2 Zeilen ausdrucken (aus den 3 Eingabezeilen) ... aber im 4. Fall bekomme ich nur 1 Zeile (für beide sort -u
und uniq
); Die beiden identischen Lins verschwinden einfach!
Ich habe die Ausgabe '\ n' für eine kompakte Ansicht in Platz konvertiert.
Ich verwende Uniq und sortiere nach (GNU Coreutils) 7.4 ... und laufe auf Ubuntu 10.04.3 LTS Desktop.
Das Skript:
{
locale -k LC_COLLATE
echo
for c1 in x 〼 ;do
for c2 in z 〇 ;do
echo -n "asis : "; echo -e "$c1\n$c2\n$c2" |tr '\n' ' ';echo
echo -n "uniq : "; echo -e "$c1\n$c2\n$c2" |uniq |tr '\n' ' ';echo
echo -n "sort -u: "; echo -e "$c1\n$c2\n$c2" |sort -u |tr '\n' ' ';echo
echo
done
echo
done
}
Die Ausgabe:
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2081
collate-codeset="UTF-8"
asis : x z z
uniq : x z
sort -u: x z
asis : x 〇 〇
uniq : x 〇
sort -u: 〇 x
asis : 〼 z z
uniq : 〼 z
sort -u: 〼 z
asis : 〼 〇 〇
uniq : 〼
sort -u: 〼
# In the last example (of 4) where did the '〇' go? .. U+3007 IDEOGRAPHIC NUMBER ZERO
#
sort
allein (ohne die Option -u ) ... verschlingt keine Zeichen. Was rein geht, kommt raus ... Wie Gilles Erklärung der "exotischen" Unicode-Zeichen mit dem gleichen kanonischen Wert erwartet , sind dies jedoch Zeichen werden nicht sortiert, außer dass sie als unsortierte FIFO-Gruppe an die "Spitze" der Sortierausgabe ausgegeben werden ... Hier gibt es also wirklich zwei Probleme: 1. Die Zeichen werden nicht so sortiert, wie es "naiv" sein könnte "erwartet und 2. Die" einzigartige "Funktion von beidensort
unduniq
Datenverlust (in einigen Fällen).sort -u
und gutuniq
funktioniert mit:LC_COLLATE=C; echo -e "〼\n〇\n〇" |sort -u
(oder|uniq
)Antworten:
Kurzversion: Die Sortierung funktioniert in Befehlszeilenprogrammen nicht wirklich.
Längere Version: Die zugrunde liegende Funktion zum Vergleichen von zwei Zeichenfolgen ist
strcoll
. Die Beschreibung ist nicht sehr hilfreich, aber die konzeptionelle Methode besteht darin, beide Zeichenfolgen in eine kanonische Form umzuwandeln und dann die beiden kanonischen Formen zu vergleichen. Die Funktionstrxfrm
konstruiert diese kanonische Form.Beobachten wir die kanonischen Formen einiger Strings (mit GNU libc unter Debian Squeeze):
Wie Sie sehen können, haben 〼 und 〇 dieselbe kanonische Form. Ich denke, das liegt daran, dass diese Zeichen in den Sortiertabellen des
en_US.UTF-8
Gebietsschemas nicht erwähnt werden . Sie sind jedoch in einem japanischen Gebietsschema vorhanden.Der Quellcode für die Gebietsschemadaten (in Debian Squeeze) befindet sich in
/usr/share/i18n/locales/en_US
, einschließlich/usr/share/i18n/locales/iso14651_t1_common
. Diese Datei hat keinen Eintrag fürU3007
oderU303C
und ist auch nicht in einem Bereich enthalten, den ich finden kann.Ich bin nicht mit den Regeln zum Erstellen der Sortierreihenfolge vertraut , aber nach meinem Verständnis ist die relevante Formulierung
Es sieht so aus, als würde Glibc stattdessen Zeichen ignorieren, die nicht angegeben sind. Ich weiß nicht, ob mein Verständnis der POSIX-Spezifikation fehlerhaft ist, ob ich etwas in der Gebietsschemadefinition von Glibc übersehen habe oder ob ein Fehler im Glibc-Gebietsschema-Compiler vorliegt.
quelle
charmaps/UTF-8
sagt nichts über Kollation, es istlocales/en_US
wichtig. Die erste RegelLC_COLLATE
lautet: Nicht verwendenLC_COLLATE
. Im Gebietsschema C (= POSIX) ist die Sortierung sinnvoll (ausschließlich basierend auf numerischen Zeichenwerten).LC_COLLATE=C
... danke ...Um
sort
Unicode-Zeichenfolgen "sicher" zu machen , schauen Sie sich vielleicht Folgendes anmsort
:http://www.billposer.org/Software/msort.html
quelle
msort
. Die optionale Benutzeroberfläche erleichtert die Einführung, um ein Gefühl für das Angebot zu bekommen. Es ist sehr praktisch, den generierten Befehl kopieren zu können ... Und ja, es sortiert die Unicode-Zeichen, aber (lieben Sie nicht nur diese "Aber" :) ... aber es gibt keine eindeutige Option: (... wie auf dem Link erwähnt, den Sie gepostet haben:Capabilities of GNU sort and BSD sort lacking in msort are the ability to merge files without sorting them (the --merge option) and the ability to emit only the first of an equal run (the --unique option)
... Die Sortierung funktioniert jedoch :)