Сортировать строку по значению столбца

Сортировать строку по значению столбца

Мне нужно отсортировать дамп потока, который выглядит следующим образом:

$ 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]

Дамп довольно большой, поэтому я хотел бы отсортировать его по столбцу "cpu" (по возрастанию или убыванию). Похоже, команда sort принимает параметр "k", чтобы указать столбец, используемый в качестве критерия сортировки. "cpu" - это 5-й столбец, поэтому я попробовал:

$ 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]

Я вижу, что порядок изменился, но он не соответствует ожидаемым мною критериям ("cpu"). Есть идеи, можно ли использовать текст типа "cpu=value" в качестве критерия для сортировки или его нужно объединить с другими командами? Спасибо

решение1

Существует "шаблон" дизайна, который можно принять, сортируя целые строки на подмножестве ввода, которое само по себе не может быть извлечено напрямую. В таких случаях, делать это в многоступенчатом конвейере, как ниже, будет лучше, чем писать полноценную команду на Awk или perl

Один из способов — использовать Awk для извлечения msподстроки, преобразования ее в числовое значение и вывода всей строки вместе со значением миллисекунд, а затем выполнить сортировку на основе последнего и впоследствии обрезать его.

Передайте вывод вашей команды в следующее:

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

Для убывания времени добавьте флаг -rкsort

решение2

Если вы используете =в качестве разделителя полей, значение cpu находится в 4-м поле. Вы можете сделать

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

с -gдля «общей числовой» сортировки.

При заданных данных выход равен

"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]

Это предполагает, что знак равенства не отображается в строке, заключенной в кавычки, поэтому он не так стабилен, как ответ @Inian.

Связанный контент