我试图在一个相当大的日志文件中找到所需的日志(让我们说250 MB)。 每个日志都以
开头YYYY-MM-DD时间:
接下来是一些一行或多行文字 我想要匹配
最后以换行符和新的DateTime模式结束。
问题是如果日志中的文本是多行并且仅在下一个日志之前,如何匹配日志。 匹配值的顺序未知以及它们的行。
我尝试了下一个解决方案
grep -Pzio '^(\d{4}-\d{2}-\d{2} timePattern)(?=[\s\S]*?Value1)(?=[\s\S]*?Value2)(?=[\s\S]*?Value3)[\s\S]*?(?=(\n\1|\Z)' file.log
但即使使用了不合格的[\s\S]*?
,也只是获得了以前不匹配的日志,并且在[\s\S]*
中包含了很多其他日志,最后找到所有三个值之前匹配第一次抓捕小组,只是给了我大量的文字。
所以唯一的困难是多线,我想在这里。 将不胜感激任何帮助!
编辑0:我只需找到一个包含我尝试匹配的所有值的日志。
编辑1:示例
2018-02-09 03:52:46,347 Activity=SomeAct
@Request=<S:Body><S:RQ><S:Info><S:Key><S:First>Value1</S:First><S:Second>Value2</S:Second></S:Key></S:Info></S:RQ></S:Body>
@Response=<SOAP-ENV:Body><S:RS><S:StatusCode>FAILURE</S:StatusCode></S:RS></SOAP-ENV:Body>
2018-02-09 03:52:51,377 Activity=SomeAct
@Request=<S:Body><S:RQ><S:Info><S:Key><S:First>Value1</S:First><S:Second>Value2</S:Second></S:Key></S:Info></S:RQ></S:Body>
@Response=<SOAP-ENV:Body><S:RS><S:StatusCode>SUCCESSFUL</S:StatusCode></S:RS></SOAP-ENV:Body>
2018-02-09 03:52:52,112 Activity=SomeAct
@Response=<SOAP-ENV:Body><S:RS><S:StatusCode>FAILURE</S:StatusCode></S:RS></SOAP-ENV:Body>
@Request=<S:Body><S:RQ><S:Info><S:Key><S:First>Value1</S:First><S:Second>Value3</S:Second></S:Key></S:Info></S:RQ></S:Body>
我只需要在SUCCESFULL状态下获取value1和value2的记录。 但是没有必要在请求之后做出响应,或<first>
在<second>
或RS \ RQ之前只有一行。
答案 0 :(得分:1)
它不是很清楚您想要找到什么,但常见的方法是将Awk与自定义记录分隔符一起使用,以便记录可以是多行。或者您可以手动收集记录:
awk '/^YYYY-MM-DD time: / { if (seen1 && seen2 && seen3) print rec;
seen1 = seen2 = seen3 = 0; rec = "" }
{ rec = (rec ? rec "\n" $0 : $0 }
/Value1/ { seen1++ }
/Value2/ { seen2++ }
/Value3/ { seen3++ }
END { if (seen1 && seen2) print rec; }' file
这会收集rec
自上一个分隔符后我们看到的行,当我们看到一个新的分隔符时,我们会在重新开始之前从rec
打印前一个值,如果所有&#34;看到&#34;设置了标志,表示我们已将所有正则表达式与当前rec
中的文本进行匹配。
当我们到达文件末尾时,常见的遗漏是忘记在END
块中执行此操作。