Ich möchte zwei Dateien sortieren, kann aber keine konsistenten Ergebnisse erzielen. Es scheint, dass es Probleme mit der Sortierung gibt, aber ich kann den Grund nicht verstehen. In Beispieldateien ist das Trennzeichen ein einzelnes Leerzeichen:
Datei1:
a
b
B
A
Datei2:
a 1
b 0
B 1
A 0
Ich benutze sort -k1,1
, um diese Dateien zu sortieren und die Ausgabe ist:
sortiert1:
a
A
b
B
sortiert2:
A 0
a 1
b 0
B 1
Ich brauche diese sortierten Dateien in einem join
und es beschwert sich derzeit, dass die eine der Dateien nicht sortiert ist.
In meiner Umgebung LC_COLLATE
und LC_ALL
sind nicht eingestellt, LANG
ist eingestellt aufen_US.UTF-8
Mit LC_ALL=C sort -k1,1
der Ausgabe ist:
sortiert11:
A
B
a
b
sortiert22:
A 0
B 1
a 1
b 0
Ich brauche keine bestimmte Bestellung, ich möchte nur, dass sie sich den Ergebnissen anschließen kann. Dieser Weg join
funktioniert. Um sicher zu sein kann ich auch prepend join
mit LC_ALL=C
.
Meine Frage
Warum sorted1
a
ist in vorher A
und in sorted2
a
ist nachher A
? Was auch immer die Sortierung ist, es ist für beide sort
Befehle und ich sortiere nach Spalte 1, die in beiden Eingabedateien identisch ist.
Ausgabe von hinzugefügt ltrace -e strcoll
Datei1
sort->strcoll("B","A") =1
sort->strcoll("a","b") =-1
sort->strcoll("a","A") =-7
a
sort->strcoll("b","A") =1
A
sort->strcoll("b","B") =-7
b
B
+++ exited (status 0) +++
file2
sort->strcoll("B 1","A 0") =1
sort->strcoll("a 1","b 0") =-1
sort->strcoll("a 1","A 0") =1
A 0
sort->strcoll("a 1","B 1) =-1
a 1
sort->strcoll("b 0","B 1") =-1
b 0
B 1
+++ exited (status 0) +++
\0
. Zum Beispiel mitrecode us..dump file
.LC_ALL=C
trotzdem verwendenjoin
, insbesondere wenn die Datei Nicht-ASCII-Zeichen enthält, da alle UTF-8-Glibc-Gebietsschemas fehlerhaft sind, da viele verschiedene Zeichen und Sortierelemente dort gleich sortiert sind.Antworten:
Wie Stéphane Chazelas in dem Kommentar sagte , handelt es sich um einen Fehler in der spezifischen Implementierung von
coreutils
(incoreutils-8.22-11.el7
) durch CentOS / Red Hat, insbesondere in dem fehlerhaften Internationalisierungs-Patch (coreutils-i18n.patch
), den sie zusätzlich zu GNUs geschrieben und angewendet habencoreutils-8.22
.Ich habe es hier CentOS und hier Red Hat gemeldet . Es war bereits bekannt , bei Red Hat und dort fixiert in
coreutils-8.22-13.el7
.Dieser ist derzeit noch nicht für CentOS verfügbar (20.08.2015).
Beachten Sie der Vollständigkeit halber, dass der Fehler auch (fälschlicherweise, da der Fehler nicht vorhanden war) in Upstreams (bei GNUs ) gemeldet wurde, in denen Sie weitere Informationen dazu finden.
quelle
Ihre Standardkollatierung (en_US.UTF-8) verursacht dies. Sie sollten den Wert LC_COLLATE festlegen , um den Text wie angegeben zu ordnen.
quelle
a is before A
odera is after A
nicht beide. Wie kann eine Kollatierung zu beidem führen?sort -k1
,sort -k1
ist das gleiche wiesort
. Es sortiert nach dem Abschnitt der Zeile, der beim ersten Feld beginnt, also im Grunde genommen nach der gesamten Zeile.sort -k1,1
auf dem ersten Feld zu sortieren.A
unda
ist gleich. Der Sortierbefehl würde dann nach späteren Zeichen in der Zeile sortieren. Andernfalls würden sie in der Reihenfolge belassen, in der sie ursprünglich in der Datei angezeigt wurden. Zum Beispielac
,aa
,Ab
sollte, wie sortiert werdenaa
,Ab
,ac
, nichtAb
,aa
,ac
oderaa
,ac
,Ab
.