AIXシステムでは、3つの異なる列を正しい順序でソートしようとしています。
以下は、開き括弧間の最大実行時間(例:0時間0分1.030秒)を示すより大きなファイルからの抜粋です。ファイルの出力は並列に実行されるため、最初の列は順番に並べ替えられません。以下は、2500行から抽出された最も長く実行された10のプロセスです。これで、最も長い間実行された上位10個のプロセスを、最も短い時間から最長の時間順にソートしたいと思います。
2023-01-04 12:32:08: Table seqhi completed (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09: Table iinvd completed (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:10: Table iaudl completed (0 hrs 0 mins 1.030 Secs)
2023-01-04 12:32:11: Table ccdd_save completed (1 hrs 0 mins 1.021 Secs)
2023-01-04 12:32:13: Table upi_brordrep_tmp_aj completed (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:07: Table srdel completed (0 hrs 2 mins 1.592 Secs)
2023-01-04 12:32:09: Table iibt completed (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:10: Table atprdd completed (0 hrs 0 mins 1.018 Secs)
2023-01-04 12:33:43: Table atseld completed (0 hrs 1 mins 33.868 Secs)
2023-01-04 12:32:10: Table abc_irctd completed (0 hrs 0 mins 1.029 Secs)
上記を次のように時間、分、秒でソートしたいと思います。
2023-01-04 12:32:10: Table atprdd completed (0 hrs 0 mins 1.018 Secs)
2023-01-04 12:32:08: Table seqhi completed (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09: Table iibt completed (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09: Table iinvd completed (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:13: Table upi_brordrep_tmp_aj completed (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:10: Table abc_irctd completed (0 hrs 0 mins 1.029 Secs)
2023-01-04 12:32:10: Table iaudl completed (0 hrs 0 mins 1.030 Secs)
2023-01-04 12:33:43: Table atseld completed (0 hrs 1 mins 33.868 Secs)
2023-01-04 12:32:07: Table srdel completed (0 hrs 2 mins 1.592 Secs)
2023-01-04 12:32:11: Table ccdd_save completed (1 hrs 0 mins 1.021 Secs)
私はいくつかのソートコマンドを試しましたが、欲しいものを取得するのに問題があります。これはどのように達成できますか?
答え1
タイムスタンプと期間の間のテキストに常にスペースで区切られた3つの単語があると仮定すると(例を参照)、次のことができます。
<your-file LC_ALL=C sort -nb -k6.2,6 -k8,8 -k10,10
デフォルトの区切り文字はsort
スペースではなくスペースとスペースの間の遷移であるため、ないソートキーには先行スペースが-b
含まれます。を使用してそれらを削除するには、-b
6番目のフィールドの2番目の文字から始まるように指定された最初のキーがすぐにそこにあることを確認します(
。
すべてのキーはn
数値として解釈されます。を使用すると、LC_ALL=C
10進数の基数文字が.
ユーザーのロケールから独立している必要があります。
秒と分の部分が60を超えないとします。たとえば、後者が長くても、(0 hrs 1 mins 10.1 Secs)
後でランク付けされます。(0 hrs 0 mins 120.592 Secs)
パイプラインでtail
トップ10を獲得してください。
ソートキーが固定オフセットを持つフィールドまたはフィールドの一部でない場合、一般的なアプローチは別のツールを使用してキーを抽出し、行の先頭にコピーしてソートして削除することです。中装飾 - 並べ替え - 装飾キャンセルファッション:
d='\([[:digit:]]\{1,\}\)'
<your-file sed -n "s/^.*($d hrs $d mins $d\.$d Secs)\$/\1:\2:\3.\4:&/p" |
LC_ALL=C sort -nt: -k1,1 -k2,2 -k3,3 |
cut -d: -f4-
または、組み込みの演算子でperl
最高のe
抽出およびr
エクスポートツールを使用してください。sort
Randal L. Schwartzは、「装飾 - 整列 - 装飾解除」というイディオムの名前にちなんで命名されました。通常、次を使用します。
<your-file perl -ne '
push @records, [$_, $3 + 60 * ($2 + 60 * $1)]
if /\((\d+) hrs (\d+) mins (\d+\.\d+) Secs\)$/;
END {print $_->[0] for sort {$a->[1] <=> $b->[1]} @records}'
または使用@terdonのアプローチ同じ期間の行を重複排除すると、最初にソートプロセス中にいくつかの比較が節約されますが、ハッシュテーブルを操作するコストが発生し、最終的に効率の点で非生産的になり、最終的にソート安定性が失われる可能性があります。
答え2
パール方法:
$ perl -lne '/(\d+)\s*hrs\s*(\d+)\s*mins\s*([0-9.]+)\s*Secs/;
push @{$k{($1*60*60)+($2*60)+($3)}},$_;
}{
for $t (sort {$a <=> $b} keys(%k)){
print join "\n",@{$k{$t}}
}; ' file
2023-01-04 12:32:10: Table atprdd completed (0 hrs 0 mins 1.018 Secs)
2023-01-04 12:32:08: Table seqhi completed (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09: Table iibt completed (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09: Table iinvd completed (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:13: Table upi_brordrep_tmp_aj completed (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:10: Table abc_irctd completed (0 hrs 0 mins 1.029 Secs)
2023-01-04 12:32:10: Table iaudl completed (0 hrs 0 mins 1.030 Secs)
2023-01-04 12:33:43: Table atseld completed (0 hrs 1 mins 33.868 Secs)
2023-01-04 12:32:07: Table srdel completed (0 hrs 2 mins 1.592 Secs)
2023-01-04 12:32:11: Table ccdd_save completed (1 hrs 0 mins 1.021 Secs)
制限はありませんスティーブンの答え(0 hrs 1 mins 10.1 Secs)
、以前は正しくソートされています(0 hrs 0 mins 120.592 Secs)
。一方、これは可能性が低い問題のように見え、Stéphaneの方法は簡単で高速なので、60秒以上かかる場合を知らない限り、私はその方法を代わりに使用します。
答え3
私になじみのある「sort」コマンドは数字ではなくアルファベット順にソートするので(10,11,12は6,7,8より前にソート)、-k文字列の後に「g」を追加する必要があるかもしれません(例: "-k8 「-k8,8」の代わりに、「8g」)を使用すると、数値で並べ替えることができます。
答え4
警告:現在の回答の最初の行は(GNU)sortコマンドで、通常のAIXシステムでは機能しません。 (時にはgsortという名前でgnu-sortがインストールされることもあります)
sort -k6Vb example
どこ:
-k6
フィールド 6 から最後までソートするために使用されます。Vb
バージョンソート(人の直観による順序)で先行スペースを無視するかどうか
(\{JeffとStephen}に感謝します)