如何用awk从TXT文件提取id=12321且type为Old的请求与响应?
用AWK提取同时满足id=12321和type=Old的请求/响应块
思路说明
你的日志是按块组织的:每个块从带时间的DEBUG行开始,到</Request>或</Response>结束。我们可以用awk跟踪每个块的内容,同时检查两个条件:
- 块里有没有
id=12321 - 块里有没有
<type>Old</type>
只有两个条件都满足时,才输出整个块。
具体实现代码
把下面的脚本存成filter.awk:
BEGIN { in_block = 0 block = "" has_target_id = 0 has_old_type = 0 } # 遇到新的日志块开头,重置状态 /^\[.*\] DEBUG/ { if (in_block) { in_block = 0 block = "" has_target_id = 0 has_old_type = 0 } in_block = 1 block = $0 "\n" next } # 正在收集块内容时的处理 in_block { block = block $0 "\n" # 检查是否匹配目标id if (/id=12321/) has_target_id = 1 # 检查是否是Old类型 if (/<type>Old<\/type>/) has_old_type = 1 # 到块结尾时判断是否输出 if (/<\/Request>|<\/Response>/) { if (has_target_id && has_old_type) { printf "%s", block } # 重置状态准备下一个块 in_block = 0 block = "" has_target_id = 0 has_old_type = 0 } }
运行命令
执行下面的命令(把your_log.txt换成你的日志文件名):
awk -f filter.awk your_log.txt
或者直接用一行命令:
awk 'BEGIN{in_block=0;block="";has_target_id=0;has_old_type=0} /^\[.*\] DEBUG/{if(in_block){in_block=0;block="";has_target_id=0;has_old_type=0};in_block=1;block=$0"\n";next} in_block{block=block$0"\n";if(/id=12321/)has_target_id=1;if(/<type>Old<\/type>/)has_old_type=1;if(/<\/Request>|<\/Response>/) {if(has_target_id&&has_old_type)printf "%s",block;in_block=0;block="";has_target_id=0;has_old_type=0}}' your_log.txt
输出结果
运行后会得到你要的两个符合条件的块:
[23/10/10 14:37:44:527 EST] DEBUG <?xml version="1.1" encoding="UTF-8" ?> <Request session="lkjh" id=12321> <type>Old</type> </Request> [23/10/10 16:37:44:527 EST] DEBUG <?xml version="1.1" encoding="UTF-8" ?> <Response session="lkjh" id=12321> <type>Old</type> </Response>
小提示
如果日志里的id=前后可能有空格(比如id= 12321或id =12321),可以把匹配id的正则改成/\bid[[:space:]]*=[[:space:]]*12321\b/,这样更灵活。
内容的提问来源于stack exchange,提问作者slade
相关产品推荐
相关产品推荐

