Ordenar línea según el valor de una columna

Ordenar línea según el valor de una columna

Tengo que ordenar un volcado de subprocesos que se ve así:

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

El volcado es bastante grande, por lo que me gustaría ordenarlo por la columna "cpu" (ya sea ascendente o descendente). Parece que el comando de clasificación acepta el parámetro "k" para indicar la columna que se utilizará como criterio de clasificación. "cpu" es la quinta columna, así que probé con:

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

Veo que el orden ha cambiado pero no sigue los criterios que esperaría ("cpu"). ¿Alguna idea de si un texto como "cpu=value" se puede utilizar como criterio para ordenar o si es necesario combinarlo con otros comandos? Gracias

Respuesta1

Existe un "patrón" de diseño que se puede adoptar, mientras se clasifican líneas enteras en un subconjunto de entradas, que por sí sola no se puede recuperar directamente. En tales casos, hacer esto en una canalización de varias etapas como la que se muestra a continuación sería mejor que escribir un comando completo en Awk o Perl.

Una forma de hacerlo es usar Awk para extraer la mssubcadena, convertirla en un valor numérico e imprimir la línea completa y el valor de milisegundos, ordenar según este último y recortarlo después.

Canalice la salida de su comando a lo siguiente

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

Para orden descendente de tiempos, agregue la -rbandera asort

Respuesta2

Si lo usa =como separador de campo, el valor de la CPU está en el cuarto campo. Tu puedes hacer

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

con -gpara clasificación "numérica general".

Con los datos dados, la salida es

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

Esto supone que el signo igual no aparece en la cadena entre comillas, por lo que no es tan estable como la respuesta de @Inian.

información relacionada