在Linux中使用sed从日志文件中提取行

时间:2018-09-28 15:10:46

标签: linux unix awk sed grep

我有一个打印以下行的日志文件:

01:15:21.882 DEBUG [SampleProcess] 
Sample Message
01:15:21.882 DEBUG [SampleProcess1] 
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0
01:15:21.883 DEBUG [SampleProcess2] 

我可以使用以下sed命令提取摘要报告

 sed -n '/Summary Report/,/Sample Text4/p' samplefile.log 

但是,我还想打印生成样本报告时的时间戳记。

所以,目前使用

sed -n '/Summary Report/,/Sample Text4/p' samplefile.log

我看到的输出是

Summary Report
    Sample Text1: 126
    Sample Text2: 2330
    Sample Text3: 2331
    Sample Text4: 0

我希望输出为

01:15:21.882 DEBUG [SampleProcess1] 
    Summary Report
    Sample Text1: 126
    Sample Text2: 2330
    Sample Text3: 2331
    Sample Text4: 0

5 个答案:

答案 0 :(得分:1)

这可能对您有用(GNU sed):

sed -n '/^..:..:..\./{N;/Summary Report/!D;:a;N;/Sample Text4/!ba;s/\n/&    /gp}' file

关闭自动打印。如果当前行是时间戳记,下一行不是Summary Report,则删除第一行并重复。否则,请收集以下各行,直到Sample Text4,缩进除第一行外的所有行,然后打印并重复。

答案 1 :(得分:1)

您可以尝试

sed -n '/Process1/{:a;N;/^\n/s/^\n//;/Sample Text/{p;s/.*//;};ba};' samplefile.log

查看此链接:https://unix.stackexchange.com/questions/47942/how-to-get-all-lines-between-first-and-last-occurrences-of-patterns

答案 2 :(得分:0)

sed用于做旧的/旧的/新的全部。对于其他任何事情,您都应该使用awk:

$ awk '
    /DEBUG/ { prt() }
    { rec = rec $0 ORS }
    END { prt() }
    function prt() {
        if (rec ~ /Summary Report/) {
            printf "%s", rec
        }
        rec = ""
    }
' file
01:15:21.882 DEBUG [SampleProcess1]
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0

建立自上次调用prt()以来所有行的记录。每次您看到一条DEBUG行或在输入末尾时,如有必要,请打印记录。

在任何UNIX系统中的任何shell中使用任何awk都可以使用。

清晰,简单,强大,高效,可移植,可扩展等。

答案 3 :(得分:0)

您可以使用perl来抓取文件:

$ perl -0777 -lnE 'while (/^(?=[\d.:]+[ \t]+DEBUG[^\n]*$)(.+?)(?=^[\d.:]+[ \t]+DEBUG|\z)/gms)
                 { $s=$1; 
                   say "$s" if $s =~ m/^Sample Text4/ms  }' file
01:15:21.882 DEBUG [SampleProcess1] 
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0

这与两个前瞻性提前行^(?=[\d.:]+[ \t]+DEBUG[^\n]*$)一起使用,可将示例分成三个块,其中三个行之间用DEBUG分隔。

DEMO

有了每个块之后,就可以使用

测试子串是否在该块内
m/^Sample Text4/ms

如果找到子字符串,则打印块。


这是POSIX sed解决方案,其中涉及反转文件(使用tail -r),以反向查找两种模式,然后将文件重新组装为原始顺序:

$ tail -r file.log | sed -n '/^Sample Text4/,/DEBUG/p' | tail -r    

(将-r添加到tail是POSIX的添加fairly recent,并且可能不在您的OS中。这是在最新的BSD和OS X版本中。)

答案 4 :(得分:0)

awk '/Sample Message/{getline;print}/^S/' file

01:15:21.882 DEBUG [SampleProcess1] 
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0