3

メールログのセットがあります:mail.log mail.log.0 mail.log.1.gz mail.log.2.gz

これらの各ファイルには、次のようなタイムスタンプで始まる時系列に並べ替えられた行が含まれています。

5月3日13:21:12..。

すべての行を比較せずに、 bash(および関連するコマンドラインツール)を使用して、特定の日付/時刻の後、別の日付/時刻の前にすべてのログエントリを簡単に取得するにはどうすればよいですか?私の前日と後日は、ログファイルのどのエントリとも正確に一致しない可能性があることに注意してください。

開始タイムスタンプよりも大きい最初の行のオフセットと、終了タイムスタンプよりも小さい最後の行のオフセットを決定し、そのセクションを何らかの方法で切り取る必要があるように思われます。

4

6 に答える 6

5

最小/最大日付を「エポックからの秒数」に変換し、

MIN=`date --date="$1" +%s`
MAX=`date --date="$2" +%s`

n各ログ行の最初の単語を同じに変換します。

L_DATE=`echo $LINE | awk '{print $1 $2 ... $n}'`
L_DATE=`date --date="$L_DATE" +%s`

に到達するまで線を比較して捨てますMIN

if (( $MIN > $L_DATE )) ; then continue ; fi

に到達するまで行を比較して印刷しますMAX

if (( $L_DATE <= $MAX )) ; then echo $LINE ; fi

を超えたら終了MAX

if (( $L_DATE > $MAX )) ; then exit 0 ; fi

スクリプト全体minmaxlog.shは次のようになります。

#!/usr/bin/env bash

MIN=`date --date="$1" +%s`
MAX=`date --date="$2" +%s`

while true ; do
    read LINE
    if [ "$LINE" = "" ] ; then break ; fi

    L_DATE=`echo $LINE | awk '{print $1 " " $2 " " $3 " " $4}'`
    L_DATE=`date --date="$L_DATE" +%s`

    if (( $MIN > $L_DATE  )) ; then continue ; fi
    if (( $L_DATE <= $MAX )) ; then echo $LINE ; fi
    if (( $L_DATE >  $MAX )) ; then break ; fi
done

このファイルminmaxlog.inputで実行しました、

May 5 12:23:45 2009 first line
May 6 12:23:45 2009 second line
May 7 12:23:45 2009 third line
May 9 12:23:45 2009 fourth line
June 1 12:23:45 2009 fifth line
June 3 12:23:45 2009 sixth line

このような、

./minmaxlog.sh "May 6" "May 8" < minmaxlog.input
于 2009-05-06T04:49:20.983 に答える
1

必要な範囲内のすべての行を確認する必要があるため(必要な範囲内にあるかどうかを判断するため)、ファイル内のすべての行を意味しているわけではないと思います。最低限、ファイル内の範囲外の最初の行までのすべての行を確認する必要があります(行は日付/時刻の順序であると想定しています)。

これはかなり単純なパターンです。

state = preprint
for every line in file:
    if line.date >= startdate:
        state = print
    if line.date > enddate:
        exit for loop
    if state == print:
        print line

必要に応じて、awk、Perl、Python、さらにはCOBOLでこれを記述できますが、ロジックは常に同じです。

最初に行番号を見つけて(たとえばgrepを使用して)、その行範囲を盲目的に印刷しても、grepはすべての行(範囲外の最初の行だけでなく、すべての行)を確認する必要があるため、役に立ちませ。おそらく2回、1つは最初の行用、もう1つは最後の行用です)。

これを頻繁に行う場合は、作業を「実行するたび」から「ファイルが安定したときに1回」にシフトすることを検討してください。例としては、ログファイルの行をデータベースにロードし、日付/時刻でインデックスを付けます。

設定にはしばらく時間がかかりますが、クエリがはるかに高速になります。私は必ずしもデータベースを提唱しているわけではありません。ログファイルを1時間ごとのログに分割することで、おそらく同じ効果を得ることができます。

2009/
  01/
    01/
      0000.log
      0100.log
      : :
      2300.log
    02/
    : :

次に、一定の時間、どこから探し始め、どこで見るのをやめるかを正確に知っています。範囲は次の2009/01/01-15:22よう2009/01/05-09:07になります。

  • ファイルの一部(最後のビット)2009/01/01/1500.txt
  • すべてのファイル2009/01/01/1[6-9]*.txt
  • すべてのファイル2009/01/01/2*.txt
  • すべてのファイル2009/01/0[2-4]/*.txt
  • すべてのファイル2009/01/05/0[0-8]*.txt
  • ファイルの一部(最初のビット)2009/01/05/0900.txt

もちろん、毎回手動で実行するのではなく、これらの行を返すスクリプトを作成します。

于 2009-05-06T04:13:09.230 に答える
1

多分あなたはこれを試すことができます:

sed -n "/BEGIN_DATE/,/END_DATE/p" logfile
于 2011-09-20T14:20:01.873 に答える
1

これを行う方法の基本的なアイデアの1つを次に示します。

  1. ファイルの日付スタンプを調べて、無関係かどうかを確認します
  2. 関連する可能性がある場合は、必要に応じて解凍し、ファイルの最初と最後の行を調べて、開始時刻または終了時刻が含まれているかどうかを確認します。
  3. 含まれている場合は、再帰関数を使用して、ファイルの前半または後半に開始時刻が含まれているかどうかを判断します。再帰関数を使用すると、約 20 回の比較で 100 万行のログファイルから任意の日付を見つけることができると思います。
  4. 最初のエントリのオフセットから最後のエントリのオフセットまで順にログファイルをエコーし​​ます (これ以上の比較はありません)。

私が知らないのは、ファイルの n 行目を最もよく読み取る方法 ( tail n+**n |head 1** を使用するのはどのくらい効率的ですか?) です。

何か助けはありますか?

于 2009-05-06T12:51:35.147 に答える
0

Bash環境では可能かもしれませんが、文字列と日付を操作するためのより多くの組み込みサポートを備えたツールを実際に利用する必要があります。たとえば、Rubyには日付形式を解析する機能が組み込まれているようです。次に、それを簡単に比較できるUnixタイムスタンプ(エポックからの秒数を表す正の整数)に変換できます。

irb> require 'time'
# => true

irb> Time.parse("May 3 13:21:12").to_i
# => 1241371272  

その後、Rubyスクリプトを簡単に作成できます。

  • 開始日と終了日を指定します。それらをこのUnixタイムスタンプ番号に変換します。
  • ログファイルを1行ずつスキャンし、日付をUnixタイムスタンプに変換して、開始日と終了日の範囲内にあるかどうかを確認します。

注:整数の比較は非常に簡単で効率的であるため、最初にUnixタイムスタンプ整数に変換すると便利です。

「すべての行を比較せずに」とおっしゃいました。ログファイルのどこでエントリが古すぎるか、またはその間のすべての値をチェックせずに新しすぎるかを「推測」するのは困難になります。ただし、実際に単調に増加する傾向がある場合は、次のエントリが新しすぎる(またはデータのレイアウトによっては古い)とすぐに検索を停止できるため、行の解析をいつ停止するかがすぐにわかります。それでも、希望する範囲の最初の行を見つけるという問題があります。


あなたの編集に気づきました。これが私が言うことです:

その開始エントリと終了エントリを効率的に見つけることを本当に心配している場合は、それぞれに対してバイナリ検索を実行できます。または、bashツールでそれがやり過ぎまたは難しすぎると思われる場合は、行の5%(20分の1)のみを読み取り、正確な答えにすばやく近づき、必要に応じてそれを調整するヒューリスティックを使用できます。これらは、パフォーマンスを改善するためのいくつかの提案にすぎません。

于 2009-05-06T04:03:57.020 に答える