
Ich versuche, einige Daten mit zu sortieren sort
. Mir ist aufgefallen, dass die Sortierung nach Ziffern und nicht nach Zahlen erfolgt, also habe ich das -n
Flag hinzugefügt. Allerdings wird dann scheinbar nur das erste Feld numerisch sortiert. Die Aufschlüsselung nach Feldern ist ein Problem, da die Zeilen unterschiedliche Zahlen von Feldern haben (und ich kann das Verhalten ehrlich gesagt nicht verstehen). Hier sind einige ziemlich ähnliche Beispieldaten, mit denen ich gespielt habe:
echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" | sort -n
Input Want Expect? sort -n -n -k1,1 -k2,2 -k3,3 -k4,4…
b b 1 8 2 a 1 23 44 a 1 b a 1
23 44 8 15 a 7 23 9 a 7 b a 10
b 3 23 9 b a 1 8 15 b 1 b a 2
a 7 23 44 b a 2 8 2 b 10 b b 1
b b 2 a 1 b a 10 a 1 b 2 b b 10
a 1 a 7 b b 1 a 7 b 3 b b 2
b a 10 b 1 b b 2 b 1 b a 1 a 1
b b 10 b 2 b b 10 b 10 b a 10 b 1
b 1 b 3 b 1 b 2 b a 2 b 2
b a 1 b 10 b 2 b 3 b b 1 b 3
8 2 b a 1 b 3 b a 1 b b 10 a 7
b 10 b a 2 b 10 b a 10 b b 2 b 10
8 15 b a 10 8 2 b a 2 8 15 8 2
b a 2 b b 1 8 15 b b 1 8 2 8 15
23 9 b b 2 23 9 b b 10 23 44 23 9
b 2 b b 10 23 44 b b 2 23 9 23 44
Idealerweise würde ich es gerne auf genau dieser Maschine zum Laufen bringen, auf der GNU Coreutils Sort 5.93 läuft. Ich würde es gerne mit einfachen Unix-Tools handhaben; ich möchte das Problem nicht einfach an Perl usw. übergeben. Ich hoffe auf ein Äquivalent des [imaginären]sort --numeric-sort --all-fields --actually-work
Antwort1
Ich glaube, Ihr Problem besteht darin, dass Sie nicht verstehen, was sort
passiert. Die grundlegende Sortierung basiert auf ASCII-Zeichenwerten, wobei Zahlen vor Großbuchstaben stehen, die vor Kleinbuchstaben stehen: „1“ == 49, „A“ == 65, „a“ = 97. Das erklärt die sort
Spalte, in der Zahlen wie „23“ vor „8“ sortiert werden, die vor „b b“ steht: Der ASCII-Wert für „2“ ist 50, der ASCII-Wert für „8“ ist 56 und der für „b“ ist 98.
Beim numerischen Sortieren ( sort -n
) werden nicht numerische Einträge nach der regulären Methode sortiert, aber im Vergleich zu Zahlen wie 23 oder 8 als Null interpretiert. Da der Wert jedoch als Zahl und nicht als Zeichenwert behandelt wird, steht „8“ vor „23“. Daher werden die alphabetischen Einträge vor den numerischen Einträgen sortiert.
Am besten normalisieren Sie die Daten, sodass jede Spalte den gleichen Wertetyp aufweist (entweder ausschließlich Zahlen oder ausschließlich alphanumerische Zeichen), und sortieren sie entsprechend.
In der letzten Spalte (Sortierung nach Feld) werden zuerst die Einträge mit mehr Feldern sortiert, da Sie explizit 4 (oder mehr) Felder angeben. (1,2,3) käme also vor (1,2). Ohne diese -k
Option berücksichtigt sort die Zeile als Ganzes.
Weitere Informationen finden Sie auf derInfo Coreutils sortierenSeite.
Antwort2
echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" \
| sed -r 's/[a-z]/9999&/g' | sort -n -k1 -k2 -k3 | sed 's/9999//g'
18 2
18 15
23 9
23 44
a 1
b 1
b 2
b 3
a 7
b 10
b a 1
b b 1
b a 2
b b 2
b a 10
b b 10
Ist es das, was Sie wollen? Numerisch sortieren, wenn numerisch, und Zahlen vor anderen Zeichen?
Ich stelle jedem String eine hohe Zahl voran, um die Strings beim Sortieren ans Ende zu bringen und die hohen Zahlen (9999) am Ende zu entfernen.
Antwort3
Mit dem Vorteil einiger Jahre Entwicklungsarbeit erzeugt sort -V
man sort 8.26
genau das gewünschte Ergebnis:
$ echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n8 2\nb 10\n8 15\nb a 2\n23 9\nb 2" \
| sort -V
8 2
8 15
23 9
23 44
a 1
a 7
b 1
b 2
b 3
b 10
b a 1
b a 2
b a 10
b b 1
b b 2
b b 10