在Bash中匹配多行模式:将关联的552与210结果成对输出
嘿,这个成对输出的需求用Awk就能完美解决!我给你两种常用的方案,适配不同的日志场景~
解决方案:用Awk实现成对输出
先明确下示例场景,方便你对应调整自己的日志结构:
示例输入
log entry 552 order-123 irrelevant line log entry 210 order-123 another log 552 order-456 random text final log 210 order-456 552 order-789 (no matching 210) 210 order-999 (no matching 552)
期望输出
log entry 552 order-123 log entry 210 order-123 another log 552 order-456 final log 210 order-456
方案1:按关联ID匹配(通用场景)
如果你的552和210行是通过某个唯一标识(比如示例里的order-xxx)关联的,这个脚本最靠谱:
cmd | awk ' /552/ { # 假设关联ID是每行最后一个字段,根据实际情况改成$N(N是字段位置) id = $NF # 把552行存到数组里,用ID当键 stored_lines[id] = $0 } /210/ { id = $NF # 如果找到对应的552行,就成对打印,然后删掉已匹配的记录 if (id in stored_lines) { print stored_lines[id] print $0 delete stored_lines[id] } } # 可选:最后输出所有没找到对应210的552行,不需要就删掉这个END块 END { for (id in stored_lines) { print stored_lines[id] } } '
脚本解释:
- 遇到含
552的行,就把该行内容存在数组stored_lines里,用关联ID作为索引 - 遇到含
210的行,检查对应的ID是否在数组中:存在就先打印之前存的552行,再打印当前的210行,同时删除数组里的这条记录(避免重复匹配) END块可选,用来处理那些只有552但没有对应210的行,不需要的话直接删掉就行
方案2:按顺序匹配(552行后紧跟对应210行)
如果你的日志里,每个552行之后的第一个210行就是它的对应行(不需要ID关联),可以用更简单的状态机脚本:
cmd | awk ' /552/ { # 存下当前552行,跳过后续处理 buf = $0 next } /210/ { # 如果之前存了552行,就成对打印,清空缓存 if (buf != "") { print buf print $0 buf = "" } } '
脚本解释:
- 遇到552行就把内容存在缓存
buf里,然后跳过当前行的后续处理 - 遇到210行时,如果缓存里有内容(也就是之前存过552行),就先打印缓存的552行,再打印当前210行,然后清空缓存
这两种方案都比你原来的tee + grep组合更灵活,能直接实现成对输出的需求,你可以根据自己的日志结构选对应的脚本~
内容的提问来源于stack exchange,提问作者SwimBikeRun
相关产品推荐
相关产品推荐

