我有一个日志文件,如下所示:
Event
Process 1
Process 2
End event success
Event
Process 1
Process 3
End event error
Event
Process 1
Process 5
End event success
Event
Process 1
Process 7
End event success
Event
Process 2
Process 4
End event error
我只想保留错误事件,如下所示:
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
我尝试过,cat Event.log | awk '/Event/,/End event error/'
但这没有按我想要的方式工作。
答案1
这应该有效:
awk '/^Event/{n=1} {lines[n++]=$0} /^End event error/{for(i=1;i<n;++i) print lines[i]}' Event.log
说明:我们将“Event”之后的所有行保存到一个数组中,并在遇到“End event error”时打印它们。
答案2
用于sed
删除所有您不想提取的条目:
$ sed '/^Event$/,/^End event success$/d' file
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
答案3
$ perl -l -n -e 'BEGIN { $/ = "\nEvent" };
print "Event$_" if /End event error/' input.log
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
用作\nEvent
记录分隔符 ( $/
),它打印包含“结束事件错误”的记录。
注意:在perl中,记录分隔符是区分大小写的固定字符串(即不是正则表达式)。
如果您希望每个记录之间有一个空行(以便更容易作为段落进行后处理),请将打印语句更改为print "\nEvent$_" if ...
.
答案4
使用乐(以前称为 Perl_6)
~$ raku -e 'for lines.join("\n").split(/ \n <?before Event >/) { .put if .words[*-1] eq "error" };' file
#OR
~$ raku -e '.put if .words[*-1] eq "error" for lines.join("\n").split: / \n <?before Event >/;' file
Raku 是 Perl 家族的一种编程语言。简要地,
- Auto-chomped
lines
被读入并与\n
换行符连接。如果您不关心在输出末尾添加额外的换行符,则可以在此处使用slurp
而不是。lines.join("\n")
\n
- 该数据被存入现有插入换行符的
split
记录中(正向前瞻)。\n
<?before Event>
- Out
put
已确定if words[*-1] eq "error"
,也就是说,[*-1]
记录的最后一个空格分隔的单词是“错误”。[注意:您可以使用以下命令返回记录中任何位置不区分大小写“错误”的记录if m:i/error/
]。
输入示例:
Event
Process 1
Process 2
End event success
Event
Process 1
Process 3
End event error
Event
Process 1
Process 5
End event success
Event
Process 1
Process 7
End event success
Event
Process 2
Process 4
End event error
示例输出:
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error
请注意,您可以查看中间体以确保正确分割记录(删除if
上面的条件并添加raku
):
~$ raku -e '.raku.put for lines.join("\n").split: / \n <?before Event>/;' file
"Event\nProcess 1\nProcess 2\nEnd event success"
"Event\nProcess 1\nProcess 3\nEnd event error"
"Event\nProcess 1\nProcess 5\nEnd event success"
"Event\nProcess 1\nProcess 7\nEnd event success"
"Event\nProcess 2\nProcess 4\nEnd event error"
只是为了好玩,join
/split
在\t
选项卡上以获得真正紧凑的输出(假设输入文件中没有选项卡):
~$ raku -e '.put if .words[*-1] eq "error" for lines.join("\t").split: / \t <?before Event>/;' file
Event Process 1 Process 3 End event error
Event Process 2 Process 4 End event error