如何让Grep多字符串匹配结果与对应源IP关联输出?
我明白你的痛点——原来的命令只给你IP列表,却丢了关键的对应关系,根本没法知道哪个IP触发了哪个术语对吧?这里有几个简便的方法帮你同时捕获术语和IP,输出一目了然:
方法1:用awk(最灵活易读)
awk可以在单步处理中完成匹配术语、提取IP并关联二者的操作,逻辑清晰,后续改术语也方便:
awk '/term1|term2|term3|term4|term5/ { # 确定当前行匹配的术语 switch (1) { case /term1/: term = "term1"; break case /term2/: term = "term2"; break case /term3/: term = "term3"; break case /term4/: term = "term4"; break case /term5/: term = "term5"; break } # 提取行中的第一个IP(如果一行多个IP可以调整逻辑) if (match($0, /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/)) { ip = substr($0, RSTART, RLENGTH) print term ": " ip } }' file.log | sort
这个脚本会遍历每一行,先判断匹配的是哪个术语,再提取IP,最后输出术语: IP的格式,排序后结果非常清晰。如果你的日志里一行可能有多个IP,只要把提取IP的部分改成循环遍历所有匹配项就行。
方法2:用grep的Perl正则(更简洁)
如果你的grep支持-P选项(大部分Linux发行版都支持),可以用捕获组直接匹配术语和IP,再用awk整理格式:
grep -oP '(term1|term2|term3|term4|term5).*?([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})' file.log | awk -F'[0-9]' '{term=$1; ip=substr($0, length(term)+1); print term ": " ip}' | sort
这里grep负责找出同时包含术语和IP的片段,awk把片段拆成术语和IP,再格式化输出。如果术语在IP后面,把正则改成([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*?(term1|term2|term3|term4|term5)就行。
小提示
如果想统计每个术语对应的IP出现次数,只要在最后加个uniq -c就行,比如:
# 基于awk方法的统计 awk '/term1|term2|term3|term4|term5/ { switch (1) { case /term1/: term = "term1"; break case /term2/: term = "term2"; break case /term3/: term = "term3"; break case /term4/: term = "term4"; break case /term5/: term = "term5"; break } if (match($0, /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/)) { ip = substr($0, RSTART, RLENGTH) print term ": " ip } }' file.log | sort | uniq -c
这样你还能看到每个术语对应的IP出现了多少次,排查问题更高效。
内容的提问来源于stack exchange,提问作者JSimonsen
相关产品推荐
相关产品推荐

