join: "Datei 2 nicht in sortierter Reihenfolge"

12

Ich habe zwei Dateien _jeter3.txt und _jeter1.txt

Ich habe überprüft, ob beide nach der 20. Spalte sortiert sind sort -c

sort -t '     ' -c -k20,20 _jeter3.txt
sort -t '     ' -c -k20,20 _jeter1.txt
#no errors

aber es gibt einen Fehler, wenn ich zu joinbeiden Dateien möchte, heißt es, dass die zweite Datei nicht sortiert ist:

join -t '   ' -1 20 -2 20 _jeter1.txt _jeter3.txt > /dev/null
join: File 2 is not in sorted order

Ich verstehe nicht warum.

cat /etc/*-release #FYI
openSUSE 11.0 (i586)
VERSION = 11.0

UPDATE : Die Verwendung von ' sort -f' und join -i(beide ohne Berücksichtigung der Groß- und Kleinschreibung) behebt das Problem. Aber es erklärt nicht mein anfängliches Problem.

UPDATE : Versionen von sort & join:

> join --version
join (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)

> sort --version
sort (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)
Pierre
quelle
Können Sie uns der Vollständigkeit halber die Ausgabe von "join --version" und "sort --version" geben? Ich kann unter keinen Umständen einige ältere Versionen von gnu dazu bringen, mir diese Fehlermeldung zu geben.
Bruce Ediger
3
Bitte posten Sie einige Beispieldaten, die das Problem und die Ausgabe von aufweisen locale.
Gilles 'SO- hör auf böse zu sein'

Antworten:

25

Ich habe den gleichen Fehler mit Ubuntu 11.04, mit sortund joinbeiden in Version (GNU coreutils) 8.5.

Sie sind eindeutig nicht kompatibel. Tatsächlich sortscheint der Befehl fehlerhaft zu sein: Es gibt keinen Unterschied mit oder ohne die Option -f( --ignore-case). Beim Sortieren aaBsteht immer vor aBa. Nicht alphanumerische Zeichen scheinen auch immer ignoriert zu werden ( abcsteht davor ab-x)

Join scheint das Gegenteil zu erwarten ... Aber ich habe eine Lösung

Tatsächlich ist dies mit der Kollatierungssequenz verknüpft: Mit LANG=en_EN sort -k 1,1 <myfile> ...then wird LANG=en_EN join ...die Nachricht entfernt.

Internationalisierung ist die Wurzel des Bösen ... (niemand dokumentiert dies eindeutig).

Michael
quelle
Also, wenn beide verwenden LANG=en_EN, dann wird es auf jeden Fall funktionieren? Funktioniert es für jedes Gebietsschema, solange beide dasselbe Gebietsschema verwenden? Können wir sagen, dass der Unterschied zwischen sortund darin joinbesteht, dass standardmäßig ein anderes Gebietsschema verwendet wird?
Aaron McDaid
Ist die -kOption die Antwort hier oder ist es die LANG=en_EN? Es ist unklar, welche Lösung hier genau vorliegt.
User
5

Sortierten Sie mit Zahlen? Ich fand, dass das Auffüllen der Spalte mit Nullen, an der ich teilnahm, dieses Problem für mich löste.

cat file.txt \
     | awk -F"   " '{ $20=sprintf("%06s", $20); print $0}' \
     | sort > readytojoin.txt
Conor
quelle
5

Wenn Sie sicher sind, dass Sie Ihre Eingabedateien richtig sortiert haben und ihre Zeilen gepaart werden können, können Sie den obigen Fehler vermeiden, indem Sie ausführen join --nocheck-order file1.txt file2.txt

Yoav Weiss
quelle
4

sort Standardmäßig wird die gesamte Zeile als Schlüssel verwendet

join Verwendet nur das angegebene Feld als Schlüssel.

Sie müssen diese Inkompatibilität korrigieren, indem Sie die Sortierung so einschränken, dass nur der Schlüssel verwendet wird, an dem Sie teilnehmen möchten.

In der Manpage Join heißt es:

Wichtig: DATEI1 und DATEI2 müssen in den Verknüpfungsfeldern sortiert sein. Verwenden Sie beispielsweise 'sort -k 1b, 1', wenn> 'join' keine Optionen hat. Beachten Sie, dass Vergleiche die durch 'LC_COLLATE' angegebenen Regeln berücksichtigen. Wenn die Eingabe> nicht sortiert ist und einige Zeilen nicht verbunden werden können, wird eine Warnmeldung ausgegeben.

PeterVermont
quelle
2
LOCALE=C sort ...
LOCALE=C join ...

Dies wird Ihr Problem lösen. Das Problem ist, wie von @Michael hervorgehoben, die Kollatierungssequenz, die von Ihrer LOCALE-Einstellung abhängt.

Jignesh Smart
quelle
2

Beachten Sie, dass Sie möglicherweise auch das Trennzeichen für den Sortierbefehl festlegen müssen, wenn dieser Fehler auftritt und Sie bereits nach einer bestimmten Spalte sortiert haben und Ihren Kopf gegen die Wand schlagen, z. B. -k4,4 sortieren

Anscheinend hat OP dies bereits mit -t '' getan, aber für einen normalen tabulatorgetrennten Text würde ich empfehlen

sort -t $'\t' ...

Der Sortierbefehl kann standardmäßig Leerzeichen als Trennzeichen enthalten, selbst wenn es sich um eine durch Tabulatoren getrennte Datei handelt (insbesondere, wenn die Spalte, nach der Sie sortieren, Leerzeichen enthält).

Dann, wenn Sie die sortierten Daten übergeben, um beizutreten, und Sie haben

join -t $'\t' ...

Dies führt dann dazu, dass die Fehlermeldung darüber nicht sortiert wird. Wie oben erwähnt, akzeptiert der Join möglicherweise -t '' nicht.

Colin D
quelle
1

Beim Join ist das Argument nach -t ein Zeichen. Für sort können Sie ein längeres Sortiertrennzeichen angeben. Ich denke, dass Sie möglicherweise die Dateien auf einem anderen Feld zusammenfügen, das Sie möchten, und den Fall zu ignorieren, löst das Problem durch Zufall.

Und ich stimme Gilles zu, dass Beispieldaten hilfreich wären.

Paweł Brodacki
quelle