命令提取兩行之間的數據

命令提取兩行之間的數據

我必須從日誌檔案中的行號開始提取異常和相應的堆疊追蹤。我知道錯誤的起始行號。我如何從下面的範例中找出堆疊追蹤的結束位置?感謝你的幫助

例子
--------
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 個字元(數字或短劃線後跟空格)開頭,則設為零。換句話說,f在以日期開頭的第一行設定為零。

    如果需要,我們可以使用更複雜的正規表示式來識別日期的開始。例如,以下內容要求該行以看起來像資料的內容開頭,後面跟著一個空格,然後是看起來像時間的內容,最後跟著一個逗號。

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

    對此還可以進一步改進。

  • f{print}

    如果f非零,則列印該行。

    為簡潔起見,我們可以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}

相關內容