Linux: Letzte Spalte sortieren

Linux: Letzte Spalte sortieren

Ich führe ein Skript aus (über das ich keine Kontrolle habe), um die folgende Ausgabe zu erhalten. Ich möchte nach der letzten (dritten) Spalte sortieren. Jede Spalte ist durch Leerzeichen getrennt und die zweite Spalte enthält Leerzeichen/Symbole.

    > ./script
    37622       (this is || test1)&&(SGD||HKD||RMB)     40010
    43944       (this is)&&(SGD||HKD)    102732
    79378       (this is||test2)&&(HKD||RMB)    205425
    457000      (test2) && (SGD||RMB||HKD||YEN)        71
    559658      (test1||test2)&&(RMB||YEN||SGD)     14043

Ich habe versucht, sort -k zu verwenden, aber es funktioniert nicht. Dann habe ich diese Frage gefunden -Wie erfolgt eine numerische Sortierung nach der letzten Spalte?- die angebotene Lösung ist

awk '{print $NF,$0}' file.txt | sort -nr | cut -f2- -d' '

Meine Frage lautet: Wie nutze ich dies, wenn ich das Skript ausführe?

    > ./script | <something??>

Danke schön.

Antwort1

Ohhhh

Sie können die verknüpfte Pipe auf einfache Weise anpassen:

$ ./script | awk '{ print $NF,$0 }' | sort -k1,1 -n | cut -f2- -d' '

Im awkAusdruck $xwird die x-te Spalte der aktuellen Zeile referenziert (beginnend mit 1) - und die vordefinierte Variable NFspeichert die Anzahl der Spalten der aktuellen Zeile, print $NF,$0druckt also für jede Zeile die letzte Spalte und die komplette Zeile (weil $0kennzeichnet die komplette Zeile). Der cutBefehl gibt dann die vorletzte Spalte jeder Zeile aus.

Der -k1,1Teil Sort bedeutet, dass nur die erste Spalte als Sortierschlüssel verwendet wird - das macht nur einen Unterschied, wenn mehrere Zeilen den gleichen Wert in der ersten Spalte haben. Ohne -k1,1beeinflussen in diesem Fall die nachfolgenden Spalten die relative Reihenfolge (als sekundärer usw. Sortierschlüssel). Mit -k1,1wird nur die erste Spalte als Sortierschlüssel verwendet - und die relative Reihenfolge der Zeilen mit gleichem Schlüssel wird nicht verändert (d. h. es wird eine stabile Sortierung durchgeführt).

sed

Alternativ können Sie das Problem auch über sortund lösen sed:

$ ./script | sed 's/^\(.\+[ \t]\+\)\([0-9]\+ *\)$/\2 \1/' | \
     sort -k1,1 -n | sed 's/^\([0-9]\+\) \(.\+\)$/\2 \1/'

Wobei der Zeilenumbruch am Ende der ersten Zeile via maskiert wird \– das können Sie entfernen \und die Pipe als eine Zeile eingeben.

Die Idee dahinter ist, die letzte Spalte zunächst nach vorne zu schieben, nach der ersten Spalte zu sortieren und diese dann wieder nach hinten zu verschieben.

Es wird davon ausgegangen, dass die letzte Spalte durch Leerzeichen, also [ \t]\+Leerzeichen oder Tabulatoren, getrennt ist.

Die sedAusdrücke führen die Vertauschung über Gruppenreferenzen durch (z. B. \2 \1) - die Gruppen werden im Muster durch maskierte Klammern markiert:\(...\)

verwandte Informationen