开发时如果需要检索一段时间内或者某个批量执行期间的所有日志,也就是区间日志时,手动检索会有一些问题:
- 如要查询一段时间前的日志(比如归档日志),需要一页一页翻,费时且费眼睛
- 使用
grep筛选日志,但是只能搜索满足特定字段的日志,无法检索区间日志
为了实现区间日志的检索,可以使用sed/awk命令。这两个命令都无法直接处理压缩文件,需要先使用zcat读取压缩文件再通过管道传递。
1 grep+sed
sed是一个流编辑器,它一次读取一行文本,处理一行并输出一行,要检索日志区间时,主要使用
1 2 3 4 |
|
行号匹配注意:
startrow,endrow为起始行号,结束行号,p为打印命令(print)sed默认处理一行之后会输出一行,因此需要使用-n+p来取消自动打印,只打印我们需要的行- 如果只有一个行号,则打印指定行
- 打印到末尾,则区间为
startrow,$
字符匹配注意:
sed匹配字符时,一旦匹配到start则会一直输出内容直到匹配到end,因此:
- 如果文件包含多个顺序
start...end,则会分批输出 - 如果只有
start,没有end,则会从start输出到文件末尾 - 如果文件内容为
start...start...end...end,那么会输出从第一个start到第一个end区间里内容
匹配区间时候一般使用(真实使用这个最方便):
1 2 3 4 |
|
2 awk
sed一般只用于简单的文本转换编辑,比如查找替换,但awk命令是一个更强大的文本处理器,可以处理更复杂的命令,比如计算、分析。
awk采用“模式-动作”对执行模型,命令基本结构是:
1 2 3 |
|
对于输入流/文件里的每一行,awk会依次检查每个pattern,如果匹配成功,则执行对应的action,如果某个action之后的pattern不需要继续匹配,则需在这个action中加上next终止后续匹配。如果action缺失,则采用默认动作{print $0},打印当前整行。
如果要打印开始日志到结束日志中间的内容,使用如下命令,与sed一样,如果文件包含多组开始日志...结束日志,则会输出所有区间:
1 2 3 4 5 6 7 |
|
命令1.1的流程为:
- 当匹配
开始日志行时,将开关变量flag置1,然后执行next跳过后续模式动作处理,直接读取下一行 - 假设下一行是中间行,那么前两个正则匹配模式都失败,进行第三个
flag模式,这是一个表达式模式,检查flag的值。当它非0或非空时为true,然后采用默认动作{print $0},打印当前整行,因此中间行能被打印 - 当匹配
结束日志行时,开关变量flag置0,继续下一个模式,此时flag表达式判断为false,因此不打印
这个流程完成了从开始日志行到结束日志行之间内容的打印。1.2同样可以按照这个流程分析,它会打印包括开始日志行和结束日志行在内的所有区间内容。
命令2是范围模式,格式为pattern1,pattern2 {action},是一种特殊模式,它表示从第一次匹配pattern1的行开始,到第一次匹配pattern2的行结束,之间的所有行都执行action动作。action缺失则打印整行。
3 sed/awk查找特定重复区间
当某功能或任务执行多次时,可能有多个任务开始...任务结束区间:
1 2 3 4 5 6 7 8 |
|
3.1 查找第一个区间
sed/awk查找第一个区间日志都是在输出完后退出,sed使用q,awk使用exit:
1 2 3 |
|
3.2 查找第n区间
如果想要找到第n组日志可以用awk定义计数器(sed不支持复杂操作):
1 |
|
3.3 最后一组/最新组
sed,awk都是流处理,无法回溯信息,因此无法得知当前区间是否是最后一次,所以最新一组日志需要使用反转命令找第一次结束日志...开始日志区间,再倒转即可。
1 2 3 |
|
到此这篇关于linux sed/awk命令检索区间日志的问题的文章就介绍到这了