範囲に特定の文字列が含まれている場合は、日付範囲間のログ範囲を取得する

範囲に特定の文字列が含まれている場合は、日付範囲間のログ範囲を取得する

検索文字列が存在する場合、特定の日付範囲内のファイルから複数行の範囲を検索しています。私はUnixの専門家ではなく、これを実装する方法がわかりません。インターネット検索の後、awkコマンドとsedコマンド(以下の説明)を使用して日付範囲内のログを表示できますが、検索条件を追加することはできません。ログファイルの形式は次のとおりです。

ログファイルの内容

[2020/07/05 21:10:28.961][INFO ][ABCDDDDDDD]
------------------------------------------------------------
ID: ABCDDGSDFEWRER
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
  "ID" : 1,
  "BC" : 9789,
  "event" : "something",
  COMMON_TEXT: COMMON
    "valid" : true
}
************************************************************
[2020/07/05 21:10:28.816][INFO ][ABCDDDDDEEEEEEE]
------------------------------------------------------------
ID: ABCDDSDFSDFSDFSDFSDFSDFSDFFEWRER
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
  "ID" : 1,
  "BC" : 9089,
  "event" : "One More thing",
  COMMON_TEXT: COMMON
    "valid" : true
}
************************************************************
[2020/07/05 21:10:43.816][INFO ][ABCDDDDDEEFFFFFFFFFFFFFEEE]
------------------------------------------------------------
ID: QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
  "ID" : 1,
  "BC" : 9789,
  "event" : "Second thing",
  COMMON_TEXT: COMMON
    "valid" : False
}
************************************************************

現在使用しているコマンドは次のとおりです。

  • awk:(sedコマンドは正しい開始時間を認識しないため、正確な開始時間を取得してください)
    awk 'substr($1,2,11)>="2020\/07\/05" && substr($1,2,11)<="2020\/07\/05" && substr($2,1,8)>="21:10:28" && substr($2,1,8)<="21:10:43" {print $0}' logfileName
    
  • sed:指定された時間範囲のログを取得します(2つの日付間のブロック)。中間ブロックを印刷する必要はありません(私の時間範囲内ですが9789が含まれていないため)。
    sed -n '/2020\/07\/05 21:10:28.010/,/2020\/07\/05 21:10:30.668/{;p};/2020\/07\/05 21:10:30.668/,/\*\*\*/{;p}' logfileName
    

以下は私が探している結果のサンプルです。 1.以下の2つのブロックは私が望む時間制限内にあります。 2.これには「BC」が含まれています:9789(希望の数字)現在、上記の2つのコマンドを使用しています。 Javaコードを使用して中間ブロックを削除して、結合と検証(9789)を処理します。

[2020/07/05 21:10:28.961][INFO ][ABCDDDDDDD]
------------------------------------------------------------
ID: ABCDDGSDFEWRER
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
  "ID" : 1,
  "BC" : 9789,
  "event" : "something",
  COMMON_TEXT: COMMON
    "valid" : true
}
************************************************************
[2020/07/05 21:10:43.816][INFO ][ABCDDDDDEEFFFFFFFFFFFFFEEE]
------------------------------------------------------------
ID: QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
  "ID" : 1,
  "BC" : 9789,
  "event" : "Second thing",
  COMMON_TEXT: COMMON
    "valid" : False
}
************************************************************

ベストアンサー1

次の理由で少し冗長です。

..1回限りではないと仮定し、変数を適切に公開してスクリプトの引数にします。

..読みやすく適応可能です。

..タイムスタンプからすべてのアスタリスクを含む次の行まで、ログエントリブロック全体を表示します。

#! /bin/bash

Low='2020/07/05 21:10:28'
End='2020/07/05 21:10:43'

AWK='
BEGIN { 
    reTS = "[[]20../../.. ..:..:..[.]...[]]";
    reStop = "^[*]+$";
}
function Range (ts) {
    return ((ts < Low || ts > End) ? "N" : "Y");
}
match ($0, reTS) { Block = Range( substr ($0, RSTART+1, RLENGTH-6)); }
Block == "Y" { print; }
$0 ~ reStop { Block = "N"; }
'
    awk -v Low="${Low}" -v End="${End}" "${AWK}" myLog.txt

おすすめ記事