列の値に基づいて行を並べ替える

列の値に基づいて行を並べ替える

次のようなスレッド ダンプをソートする必要があります。

$ 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 で本格的なコマンドを書くよりも優れています。

1 つの方法としては、Awk を使用してms部分文字列を抽出し、数値に変換して行全体とミリ秒の値を出力し、後者に基づいて並べ替えて、後で切り捨てるという方法があります。

コマンド出力を次のものにパイプします

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

降順で並べるには、フラグ-rsort

答え2

フィールドセパレータとして使用する場合=、CPU値は4番目のフィールドにあります。次のようにすることができます。

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

-g「一般的な数値」ソートの場合はwith を使用します。

与えられたデータからの出力は

"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 の回答ほど安定していません。

関連情報