如何使用Grep提取日志中对应'targetServerType: database'的前置时间戳
提取对应错误日志的时间戳解决方案
我明白你想要提取所有包含targetServerType: database错误对应的日志起始时间戳,之前的grep命令没能精准提取捕获组,下面给你几个可行的方案:
方案一:Perl 命令(最直接)
Perl 对多行正则和捕获组的支持非常友好,用它可以一步到位提取目标时间戳:
perl -0777 -ne 'while (/^([0-9]{4}-[0-1][0-9]-[0-3][0-9]\s([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])(?:.*?)(targetServerType: database)$/gms) { print "$1\n" }' server.log
-0777:将整个日志文件作为单个字符串读取,处理跨多行的内容/gms:g表示全局匹配所有符合条件的区块,m让^匹配每一行的开头,s让.可以匹配换行符- 正则里的
(?:.*?)是非捕获组,避免捕获不需要的中间日志内容,只聚焦我们要的时间戳捕获组$1
方案二:Grep + Sed 组合
如果更习惯用 grep,可以先匹配到包含错误的完整日志块,再用 sed 提取时间戳:
grep -Pzo '^([0-9]{4}-[0-1][0-9]-[0-3][0-9]\s([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])(?:\n|.)*?targetServerType: database$' server.log | sed -n 's/^\([0-9]\{4\}-[0-1][0-9]-[0-3][0-9]\s[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\).*/\1/p'
grep -Pzo:-P启用Perl正则,-z将换行符视为普通字符处理多行,-o输出匹配的完整区块sed命令则从每个匹配区块的开头提取时间戳,只输出我们需要的部分
为什么你之前的命令没成功?
你的原grep命令虽然能匹配到目标日志块,但-o参数只会输出整个匹配的内容,而不是你定义的第一个捕获组。grep本身没有直接输出指定捕获组的功能,所以需要结合其他工具或者换用Perl来直接提取捕获组内容。
运行上面的命令后,你就能得到期望的输出:
2022-07-10 15:24:55 2022-07-09 13:12:42
内容的提问来源于stack exchange,提问作者st.
相关产品推荐
相关产品推荐

