Ich versuche, nach mehreren Spalten zu sortieren. Die Ergebnisse sind nicht wie erwartet.
Hier sind meine Daten (people.txt):
Simon Strange 62
Pete Brown 37
Mark Brown 46
Stefan Heinz 52
Tony Bedford 50
John Strange 51
Fred Bloggs 22
James Bedford 21
Emily Bedford 18
Ana Villamor 44
Alice Villamor 50
Francis Chepstow 56
Folgendes funktioniert korrekt:
bash-3.2$ sort -k2 -k3 <people.txt
Emily Bedford 18
James Bedford 21
Tony Bedford 50
Fred Bloggs 22
Pete Brown 37
Mark Brown 46
Francis Chepstow 56
Stefan Heinz 52
John Strange 51
Simon Strange 62
Ana Villamor 44
Alice Villamor 50
Folgendes funktioniert jedoch nicht wie erwartet:
bash-3.2$ sort -k2 -k1 <people.txt
Emily Bedford 18
James Bedford 21
Tony Bedford 50
Fred Bloggs 22
Pete Brown 37
Mark Brown 46
Francis Chepstow 56
Stefan Heinz 52
John Strange 51
Simon Strange 62
Ana Villamor 44
Alice Villamor 50
Ich habe versucht, nach Nachnamen und dann nach Vornamen zu sortieren, aber Sie werden sehen, dass die Villamors nicht in der richtigen Reihenfolge sind. Ich hatte gehofft, nach Nachnamen zu sortieren und dann, wenn die Nachnamen übereinstimmen, nach Vornamen zu sortieren.
Es scheint, dass es etwas gibt, wie das funktionieren soll, was ich nicht verstehe. Ich könnte das natürlich auch anders machen (mit awk), aber ich möchte sort verstehen.
Ich verwende die Standard-Bash-Shell auf Mac OS X.
Akzeptierte Antwort:
Eine Schlüsselspezifikation wie -k2
bedeutet, alle Felder von 2 bis zum Zeilenende zu berücksichtigen. Also Villamor 44
endet vor Villamor 50
. Da diese beiden nicht gleich sind, erfolgt der erste Vergleich in sort -k2 -k1
reicht aus, um diese beiden Zeilen zu unterscheiden, und der zweite Sortierschlüssel -k1
wird nicht aufgerufen. Wenn die beiden Villamors gleich alt gewesen wären, -k1
hätte eine Sortierung nach Vornamen bewirkt.
Um nach einer einzelnen Spalte zu sortieren, verwenden Sie -k2,2
als Schlüsselspezifikation. Das bedeutet, die Felder von #2 bis #2 zu verwenden, also nur das zweite Feld.
sort -k2 -k3 <people.txt
ist redundant:Es entspricht sort -k2 <people.txt
. Um nach Nachnamen, dann Vornamen und dann nach Alter zu sortieren, führen Sie den folgenden Befehl aus:
sort -k2,2 -k1,1 <people.txt
oder äquivalent sort -k2,2 -k1 <people.txt
da es nur diese drei Felder gibt und die Trennzeichen gleich sind. Tatsächlich erhalten Sie den gleichen Effekt von sort -k2,2 <people.txt
, weil sort
verwendet die gesamte Zeile als letzten Ausweg, wenn alle Schlüssel in einer Teilmenge von Zeilen identisch sind.
Beachten Sie auch, dass das standardmäßige Feldtrennzeichen der Übergang zwischen einem Nicht-Leerzeichen und einem Leerzeichen ist, sodass die Schlüssel die führenden Leerzeichen enthalten (in Ihrem Beispiel lautet der erste Schlüssel für die erste Zeile "Emily"
, aber der zweite Schlüssel " Bedford"
. Fügen Sie das -b
hinzu Option zum Entfernen dieser Leerzeichen:
sort -b -k2,2 -k1,1
Dies kann auch auf Schlüsselbasis erfolgen, indem der b
hinzugefügt wird Flag am Ende der Key-Start-Spezifikation:
sort -k2b,2 -k1,1 <people.txt
Beachten Sie jedoch Folgendes:Sobald Sie der Schlüsselspezifikation ein solches Flag hinzufügen, werden die globalen Flags (wie -n
, -r
…) gelten nicht mehr für sie, daher ist es besser, das Mischen von schlüsselspezifischen Flags und globalen Flags zu vermeiden.