特定の時間範囲内のログをフィルタリングする方法

特定の時間範囲内のログをフィルタリングする方法

私のログ形式は次のとおりです(デモのために単純化されています)。

2018-04-12 14:43:00.000 ERROR hello
2018-04-12 14:44:01.000 ERROR world
2018-04-12 14:44:03.000 INFO this is a multi-line log
NOTICE THIS LINE, this line is also part of the log
2018-04-12 14:46:00.000 INFO foo

それでは、ログをフィルタリングして[2018-04-12 14:44:00.000, 2018-04-12 14:45:00.000)次の出力を生成するにはどうすればよいですか?

2018-04-12 14:44:01.000 ERROR world
2018-04-12 14:44:03.000 INFO this is a multi-line log
NOTICE THIS LINE, this line is also part of the log

答え1

そしてawk

awk -v 'start=2018-04-12 14:44:00.000' -v end='2018-04-12 14:45:00.000' '
   /^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2} / {
     inrange = $0 >= start && $0 <= end
   }
   inrange' < your-file

mawkPOSIX文字クラスとスペース正規表現演算子がサポートされていないと機能しません。

答え2

特定の時間の間に特定の行だけが必要な場合はawkそれがすべてです。簡単なチュートリアルを提供

まず、目的のルートを探します。

cat -n logfile

これにより、行番号とともにファイルの内容が表示されます。

希望の行番号を印刷するには:

awk 'NR==2,NR==4' logfile

これにより、2行と4行の範囲が印刷されます。

複数行または連続していない一連の行(必要な場合)を印刷するには、またはを||使用して区切ります。;

awk 'NR==5,NR==10;NR==15,NR==20' logfile

特定の時間範囲の間に行を印刷し続けたい場合は、上記の内容をgrepと組み合わせてくださいegrep

egrep "2018-04-12 14:44:01.000|2018-04-12 14:46:00.000" logfile | awk NR==5,NR==10

egrep複数の文字列が返されることがあります。この|記号は各文字列を区切ります。これにより、時間範囲の開始時間と終了時間(より多くの行を含むために終了時間を後の時間に変更)とその行番号を含む行が印刷されます。その後、を使用してawk2行の間(含む)の範囲を印刷できます。

これらのすべてを、例えば、ログファイルの要件と時間に応じて印刷したいコンテンツに合わせて変更できます。

答え3

現在同様の問題がありますが、1分間ログがないと、「簡単な」sed / awkメソッドは失敗します。(例:アイドルルーター)

最後に作成されたgrep最後のn分は次のように宣言されます。

searchterms() {
  backlog_minutes=15;
  for searchstamp in $(seq 0 60 $((60*backlog_minutes)));do
   LANG=en_US.UTF-8 date "+%b %d %H:%M" -d @"$(($(date +%s)-$searchstamp))";done ;
  } ;
greptarget=$(searchterms|sed 's/^/-e "/g;s/$/"/g' )

##Openwrt
which logread |grep -q logread && ( grepcmd=$(echo  grep  "$greptarget"); echo "logread|$(echo $grepcmd)"|sh )
## Linux Debian/Ubuntu
which logread |grep -q logread || (echo grep -e $greptarget /var/log/syslog|sh ;exit 0)

以前に何を試しましたか(https://unix.stackexchange.com/a/437445/374376)

##_date_syslog_15_min() { LANG=en_US.UTF-8 date "+%b %d %H:%M" -d "15 min ago"   ; } ;
##_date_syslog_now() { LANG=en_US.UTF-8 date "+%b %d %H:%M" ; } ;
## ↑↑ this ones failed when there are no log entries

答え4

あなたはこれを行うことができますsed

sed -n '/2018-04-12 14:44:00.000/,/2018-04-12 14:45:00.000/p' log_file

これは最初のインスタンスにのみ一致し、日付を区切り文字として使用して印刷することに注意する価値があります。

以下を使用して同様のものを得ることができますawk

awk '/^2018-04-12 14:44:00.000.*/,/2018-04-12 14:45:00.000.*/' log_file

関連情報