Bash中如何实现上下文关联排序,正确合并含换行的多段日志文件?
Bash多行关联日志合并排序方案
核心原理
普通sort会逐行排序,破坏首行+关联行的绑定关系,因此我们先把每个完整日志条目(时间戳首行+后续非时间戳关联行)临时合并为带时间戳前缀的单行,排序后再还原换行即可。
可用命令
针对你示例中YYYY-MM-DD HH:MM:SS格式的时间戳日志,直接运行以下命令即可得到预期结果:
awk '/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/ { if (prev) print prev prev = $0 next } { prev = prev "\0" $0 } END { print prev }' berta.log caesar.log | sort | tr '\0' '\n'
步骤说明
- awk预处理阶段
- 匹配到以指定时间格式开头的行时,先输出上一个缓存的完整日志条目,再将当前行设为新的缓存条目
- 未匹配到时间戳的行(异常堆栈、换行内容等关联行),用不可见空字符
\0拼接到当前缓存条目的末尾,保证关联行和首行绑定在同一行 - 所有文件处理完成后输出最后一个缓存的条目
- 排序阶段
预处理后的内容每个完整日志条目都是单行,首部分就是时间戳,直接用sort即可按时间正常排序,不会打乱关联关系 - 格式还原阶段
用tr命令把临时分隔用的\0替换回换行符,还原原始的多行日志格式
适配调整
如果你的日志时间戳格式不同,只需修改awk开头正则的匹配规则即可;如果日志中可能存在\0,可以把命令中所有\0替换为其他罕见不可见字符(比如\x01)即可。
内容的提问来源于stack exchange,提问作者Bowi
相关产品推荐
相关产品推荐

