数字とテキストaixを使用して3つの異なる列に基づいてソート

数字とテキストaixを使用して3つの異なる列に基づいてソート

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含まれます。を使用してそれらを削除するには、-b6番目のフィールドの2番目の文字から始まるように指定された最初のキーがすぐにそこにあることを確認します(

すべてのキーはn数値として解釈されます。を使用すると、LC_ALL=C10進数の基数文字が.ユーザーのロケールから独立している必要があります。

秒と分の部分が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エクスポートツールを使用してください。sortRandal 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}に感謝します)

関連情報