2つのログファイルが作成されたときにソートするための良い方法は何ですか?

2つのログファイルが作成されたときにソートするための良い方法は何ですか?

ログファイルを出力する2つのスクリプトを実行しています。これらのログをタイムスタンプで並べ替え、生成時に単一のファイルにマージする3番目のスクリプトを作成したいと思います。ファイルを常に上書きせずにこれを行うための良い方法はありますか?

ベストアンサー1

2つ以上のファイルをtailすると、tail -fコマンドはデータを1行ずつ表示し、データソースが変更されるたびにファイル名を出力します。この機能を使用すると、後続のタイムスタンプのある行が別のファイルで表示されるまで、各行を保持して、タイムスタンプに基づいてテールからインターリーブされた出力をマージするスクリプトを作成できます。

たとえば、私のシステムで同じ行開始タイムスタンプ形式(たとえば)を持つ2つの標準ログファイル(および/var/log/messages)を使用すると、次のことができます。/var/log/cronJun 9 02:55:01

tail -f /var/log/messages /var/log/cron |
awk '
BEGIN { num[0] = 0; num[1] = 0; }
/^==> /{
  file = $2; aa = file~/messages/?0:1; bb = 1-aa; 
  aanum = num[aa]; bbnum = num[bb];
  next }
/^$/{ next }
{ "date --date \"" $1 " " $2 " " $3 "\" +%s" | getline date
  lines[aa,aanum] = $0
  dates[aa,aanum++] = date
  maxes[aa] = date
  minmax = maxes[aa]
  if(maxes[bb]<minmax)minmax = maxes[bb]

  i = 0; j = 0;
  while(1){
    aaok = (i<aanum && dates[aa,i]<=minmax)
    bbok = (j<bbnum && dates[bb,j]<=minmax)
    if(aaok && bbok){
      if(dates[aa,i]<=dates[bb,j]){
           print lines[aa,i]; dates[aa,i++] = ""
      }else{
           print lines[bb,j]; dates[bb,j++] = ""
      }
    }else if(aaok){
           print lines[aa,i]; dates[aa,i++] = ""
    }else if(bbok){
           print lines[bb,j]; dates[bb,j++] = ""
    }else break
  }
  i = 0
  for(j = 0; j<aanum;j++)
    if(dates[aa,j]!=""){
      dates[aa,i] = dates[aa,j]; lines[aa,i++] = lines[aa,j]
    }
  aanum = num[aa] = i
  i = 0
  for(j = 0; j<bbnum;j++)
    if(dates[bb,j]!=""){
      dates[bb,i] = dates[bb,j]; lines[bb,i++] = lines[bb,j]
    }
  bbnum = num[bb] = i
}'

awkは、ファイルの先頭が最後から始まることを確認すると、2つのファイルを切り替えます==>。各ファイルごとに1つずつ4つの配列にデータを格納し、ランダムに呼び出され、aa0bbと1に番号が付けられます。datesエポック以降の秒単位のタイムスタンプを保存し、lines入力ログ行を保存し、num行数とmaxes最も高い日付をファイルに保存します。最初の2つの配列は、ファイル(0または1)と予約された行数に基づいて2次元で索引付けされます。

各ログ行を読み取ると、タイムスタンプが秒に変換され、最後に新しいエントリに保存され、その行も保存されdatesます。 2つの現在の日付の最小値はに設定されますminmax。この最小値に達するまで、保存されたデータ全体をタイムスタンプ順にスキャンして印刷します。印刷された項目が消去され、whileループが終了すると、配列が圧縮されて消去された項目が削除されます。

おすすめ記事