Sortieren Sie jedes Feld numerisch und variieren Sie die Anzahl der Felder

7

Ich versuche einige Daten mit zu sortieren sort. Ich bemerkte, dass es eher nach Ziffern als nach Zahlen sortiert war, also fügte ich die -nFlagge hinzu . Es sortiert dann aber scheinbar nur numerisch auf dem ersten Feld. Die Aufteilung nach Feldern ist ein Problem, da die Zeilen eine unterschiedliche Anzahl von Feldern aufweisen (und ich kann ihr Verhalten ehrlich gesagt nicht verstehen). Hier sind einige 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 möchte ich es auf genau dieser Maschine zum Laufen bringen, auf der GNU Coreutils Sort 5.93 vorhanden sind. Ich würde es gerne mit einfachen Unix-Tools handhaben. Ich möchte das Problem nicht einfach Perl usw. übergeben. Ich hoffe auf ein Äquivalent des [imaginären]sort --numeric-sort --all-fields --actually-work

Joel Reid
quelle

Antworten:

1

Mit dem Nutzen einiger Jahre der Entwicklung produziert sort -Von sort 8.26genau die gewünschte Leistung:

$ 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
ilkkachu
quelle
7

Ich denke, Ihr Problem ist, dass Sie nicht verstehen, was sorttut. Die grundlegende Sortierung basiert auf ASCII-Zeichenwerten, wobei Zahlen vor Großbuchstaben und vor Kleinbuchstaben stehen: '1' == 49, 'A' == 65, 'a' = 97. Dies erklärt die sortSpalte, in der Zahlen wie '23 'wird vor' 8 'sortiert, also vor' b b ': Der ASCII-Wert für' 2 'beträgt 50, der ASCII-Wert für' 8 'beträgt 56 und für' b 'beträgt 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'. Die alphabetischen Einträge werden also vor den numerischen Einträgen sortiert.

Am besten normalisieren Sie die Daten so, dass jede Spalte denselben Werttyp hat: entweder alle Zahlen oder alle alphanumerischen Zahlen, und sortieren Sie sie entsprechend.

In der letzten Spalte (nach Feld sortieren) werden die Einträge zuerst mit mehr Feldern sortiert, da Sie explizit 4 (oder mehr) Felder angeben. Also wäre (1,2,3) vor (1,2). Ohne die -kOption berücksichtigt sort die Zeile als Ganzes.

Weitere Informationen finden Sie auf der Sortierseite info coreutils .

Arcege
quelle
3
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 du willst? Numerisch sortieren, wenn numerisch, und Zahlen vor anderen Zeichen?

Ich stelle jedem String eine hohe Zahl voran, um die Strings durch Sortieren zuletzt zu setzen, und entferne am Ende die hohen Zahlen (9999).

Benutzer unbekannt
quelle