
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 awk
Ausdruck $x
wird die x-te Spalte der aktuellen Zeile referenziert (beginnend mit 1) - und die vordefinierte Variable NF
speichert die Anzahl der Spalten der aktuellen Zeile, print $NF,$0
druckt also für jede Zeile die letzte Spalte und die komplette Zeile (weil $0
kennzeichnet die komplette Zeile). Der cut
Befehl gibt dann die vorletzte Spalte jeder Zeile aus.
Der -k1,1
Teil 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,1
beeinflussen in diesem Fall die nachfolgenden Spalten die relative Reihenfolge (als sekundärer usw. Sortierschlüssel). Mit -k1,1
wird 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 sort
und 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 sed
Ausdrücke führen die Vertauschung über Gruppenreferenzen durch (z. B. \2 \1
) - die Gruppen werden im Muster durch maskierte Klammern markiert:\(...\)