2行間のデータを抽出するコマンド

2行間のデータを抽出するコマンド

ログファイルの行番号から始めて、例外とそのスタックトレースを抽出する必要があります。出発線番号を間違って知っています。次の例では、スタックトレースが終了する場所をどのように知ることができますか?助けてくれてありがとう

はい
--------
2016-10-07 15:49:07,537エラーといくつかの例外
 スタックトレースライン1
 スタックトレースライン2
 スタックトレースラインn
2016-10-07 15:49:07,539 デバッグなど
2016-10-07 15:49:07,540 デバッグなど

答え1

要約すると、指定した行番号で始まり、日付で始まる次の行の直前まで行を印刷しようとします。あなたの例では、開始行は3です。この場合:

$ awk '{if (NR==3)f=1; else if (/^[0-9-]{10} /)f=0} f{print}' trace.log
2016-10-07 15:49:07,537 ERROR Some exception
 stacktrace line 1
 stacktrace line 2
 .
 .
 stacktrace line n

上記のコードの仕組みは次のとおりです。

  • if (NR==3)f=1

    指定した行番号の変数をf1に設定します。

  • else if (/^[0-9-]{10} /)f=0

    他の行では、f行が10文字(数字またはダッシュの後にスペースが続く場合)で始まる場合は0に設定されます。つまり、f日付で始まる最初の行はゼロに設定されます。

    必要に応じて、より複雑な正規表現を使用して日付の開始を識別できます。たとえば、次の行はデータのように見える項目で始まり、その後にスペース、時間のように見える項目、最後にカンマが続く必要があります。

    awk '{if (NR==3)f=1; else if (/^[0-9-]{10} [0-9:]{8},/)f=0} f{print}' trace.log
    

    これはさらに改善することができます。

  • f{print}

    f0以外の場合は、その行を印刷します。

    簡潔にするためf{print}にに変更してくださいf。これは、ジョブを明示的に指定しない限り、デフォルトのprintジョブが使用されるため可能です。

選ぶ

awkの一部のバージョンは繰り返し要素をサポートしていません({10}システムの場合など)。

awk '{if (NR==3)f=1; else if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] /)f=0} f{print}' trace.log

答え2

すべてのスタックトレース行が空白(スペース/タブ)で始まると仮定すると、行の[[:blank:]]先頭()で一致させることができます^

grep '^[[:blank:]]' file.log

答え3

抽出するトレースが2行目から始まりtrace.log、その終わりがYYYY-MM-DD形式の日付で始まる行で表される場合(そしてトレースにそのような行がない)

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log

2行目から始めて各行を印刷します。渡すワイヤーN+3(追跡後の日付で始まる最初の行)。最後の行は必要ないので、上記の内容を最後の行を削除するコマンドにパイプすることができます。

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | head -n -1

または

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | sed '$d'

日付を検索する必要がある場合そして時間を選択し、次を検索します。

^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}

関連情報