Zeilen basierend auf dem Wert einer Spalte sortieren

Zeilen basierend auf dem Wert einer Spalte sortieren

Ich muss einen Thread-Dump sortieren, der so aussieht:

$ jstack -l 5213 | grep cpu 

"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=2.21ms elapsed=478.03s tid=0x00000000013bb800 nid=0x1465 waiting on condition  [0x00007f386cc0c000]
"Finalizer" #3 daemon prio=8 os_prio=0 cpu=1.30ms elapsed=478.03s tid=0x00000000013c6000 nid=0x1466 in Object.wait()  [0x00007f386cb0b000]
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 cpu=0.31ms elapsed=478.03s tid=0x00000000013db000 nid=0x1467 runnable  [0x0000000000000000]
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 cpu=3042.89ms elapsed=478.02s tid=0x00000000013dd800 nid=0x1468 waiting on condition  [0x0000000000000000]
"C1 CompilerThread0" #8 daemon prio=9 os_prio=0 cpu=1840.51ms elapsed=478.02s tid=0x00000000013e0000 nid=0x1469 waiting on condition  [0x0000000000000000]

Der Dump ist ziemlich groß, daher möchte ich ihn nach der Spalte „cpu“ sortieren (entweder aufsteigend oder absteigend). Es scheint, dass der Sortierbefehl den Parameter „k“ akzeptiert, um die Spalte anzugeben, die als Sortierkriterium verwendet werden soll. „cpu“ ist die 5. Spalte, daher habe ich es mit Folgendem versucht:

$ jstack -l 5213 | grep cpu | sort -k 5
"ServerService Thread Pool -- 1" #26 prio=5 os_prio=0 cpu=10.86ms elapsed=753.24s tid=0x0000000002b68800 nid=0x1482 waiting on condition  [0x00007f385c33b000]
"Transaction Expired Entry Monitor" #131 daemon prio=5 os_prio=0 cpu=0.48ms elapsed=751.66s tid=0x00000000082ed000 nid=0x14eb in Object.wait()  [0x00007f3853826000]
"Transaction Reaper Worker 0" #133 daemon prio=5 os_prio=0 cpu=0.13ms elapsed=751.63s tid=0x00000000084d9000 nid=0x14ee in Object.wait()  [0x00007f3853523000]

Ich sehe, dass sich die Reihenfolge geändert hat, aber sie folgt nicht den Kriterien, die ich erwarten würde („CPU“). Irgendeine Idee, ob ein Text wie „CPU=Wert“ als Sortierkriterium verwendet werden kann oder mit anderen Befehlen kombiniert werden muss? Danke

Antwort1

Es gibt ein Design-„Muster“, das übernommen werden kann, während ganze Zeilen anhand einer Teilmenge von Eingaben sortiert werden, die selbst nicht direkt abgerufen werden kann. In solchen Fällen wäre es besser, dies in einer mehrstufigen Pipeline wie unten zu tun, als einen vollwertigen Befehl in Awk oder Perl zu schreiben.

Sie können beispielsweise Awk verwenden, um die msTeilzeichenfolge zu extrahieren, sie in eine Zahl umzuwandeln, die gesamte Zeile und den Millisekundenwert auszudrucken und basierend auf Letzterem zu sortieren und sie anschließend auszuschneiden.

Leiten Sie Ihre Befehlsausgabe an Folgendes weiter

awk 'match($0, /cpu=[[:digit:].]+/){print substr($0, RSTART+4, RLENGTH-1)+0, $0}' | 
sort -n -k1,1 | 
cut -d' ' -f2-

Für eine absteigende Reihenfolge der Zeiten fügen Sie die -rFlagge hinzusort

Antwort2

Wenn Sie =als Feldtrennzeichen verwenden, steht der CPU-Wert im 4. Feld. Sie können

jstack -l 5213 | grep cpu | sort -t '=' -g -k4,4

mit -gfür „allgemein numerische“ Sortierung.

Mit gegebenen Daten ist die Ausgabe

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 cpu=0.31ms elapsed=478.03s tid=0x00000000013db000 nid=0x1467 runnable  [0x0000000000000000]
"Finalizer" #3 daemon prio=8 os_prio=0 cpu=1.30ms elapsed=478.03s tid=0x00000000013c6000 nid=0x1466 in Object.wait()  [0x00007f386cb0b000]
"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=2.21ms elapsed=478.03s tid=0x00000000013bb800 nid=0x1465 waiting on condition  [0x00007f386cc0c000]
"C1 CompilerThread0" #8 daemon prio=9 os_prio=0 cpu=1840.51ms elapsed=478.02s tid=0x00000000013e0000 nid=0x1469 waiting on condition  [0x0000000000000000]
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 cpu=3042.89ms elapsed=478.02s tid=0x00000000013dd800 nid=0x1468 waiting on condition  [0x0000000000000000]

Dies setzt voraus, dass das Gleichheitszeichen in der zitierten Zeichenfolge nicht vorkommt, daher ist es nicht so stabil wie die Antwort von @Inian.

verwandte Informationen