如何使用AWK计算单服务器对特定IP的访问占比?
仅用AWK实现服务器对特定IP访问占比统计问题
需求
仅使用AWK工具,评估某服务器向特定IP发送的数据是否少于其他服务器。日志包含以下字段:
- 日志时间:当日01时至24时
- 服务器名称
- 服务器访问的目标IP
- 该时段内服务器访问该IP的次数
输入示例(Iplogs.txt)
$ cat Iplogs.txt Time,Source,destinationIP,Count 11,server1,123.12.23.122,10 11,server1,125.25.45.221,153 11,server1,202.178.23.4,44 11,server2,123.12.23.122,300 11,server2,125.25.45.221,140 11,server2,202.178.23.4,41 12,server1,123.12.23.122,0 12,server1,125.25.45.221,153 12,server1,202.178.23.4,44 12,server2,123.12.23.122,300 12,server2,125.25.45.221,140 12,server2,202.178.23.4,41
预期结果
server1,125.25.45.221,306,52.21% #306/586*100 server2,125.25.45.221,280,47.78% #280/586*100 server1,202.178.23.4,88,51.76% #88/170*100 server1,123.12.23.122,10,1.63% #10/610*100 server2,202.178.23.4,82,48.23% #82/170*100 server2,123.12.23.122,600,98.36% #600/610*100
注:占比计算逻辑为单服务器对某IP的访问次数 ÷ 所有服务器对该IP的总访问次数 × 100,保留两位小数。例如1.63%是server1对123.12.23.122的访问次数10除以总次数610后乘以100得到。
已完成操作
- 统计各IP的累计访问总次数:
$ awk -F"," '{MAX[$3]+=$4} END {for(i in MAX) print i," ",MAX[i]}' Iplogs.txt 123.12.23.122 610 125.25.45.221 586 202.178.23.4 170
- 统计各服务器对各IP的累计访问次数:
$ awk -F"," '{COUNT[$2","$3]+=$4} END {for(j in COUNT) print j," ",COUNT[j]}' Iplogs.txt | sort server1,125.25.45.221 306 server2,125.25.45.221 280 server1,202.178.23.4 88 server1,123.12.23.122 10 server2,202.178.23.4 82 server2,123.12.23.122 600
当前问题
无法在同一AWK脚本中关联COUNT(服务器-IP的累计次数)和MAX(IP的总次数),计算单服务器对IP的访问占比。
解决方案
将两个统计逻辑整合到同一个AWK脚本中,一次遍历日志完成数组赋值,最后在END块中拆分联合键计算占比:
awk -F"," ' # 跳过表头行 NR==1 {next} # 同时统计IP总次数和服务器-IP的累计次数 { MAX[$3] += $4 KEY = $2 "," $3 COUNT[KEY] += $4 } END { # 遍历服务器-IP统计结果 for (key in COUNT) { # 拆分联合键为服务器和IP split(key, arr, ",") srv = arr[1] ip = arr[2] total = MAX[ip] count = COUNT[key] # 格式化占比为两位小数的百分比 ratio = sprintf("%.2f%%", (count / total) * 100) # 输出匹配预期格式的结果 printf("%s,%s,%d,%s #%d/%d*100\n", srv, ip, count, ratio, count, total) } } ' Iplogs.txt | sort
脚本说明
NR==1 {next}:跳过日志表头,避免干扰统计。MAX[$3] += $4:累计每个目标IP的总访问次数。KEY = $2 "," $3:用逗号拼接服务器名称和IP作为唯一键,区分不同服务器对同一IP的统计项。split(key, arr, ","):在END块中拆分联合键,提取服务器和IP信息。sprintf("%.2f%%", ...):将占比格式化为两位小数的百分比形式。- 末尾的
sort命令确保输出结果顺序与预期一致。
执行上述脚本后,输出将完全匹配预期结果。
内容的提问来源于stack exchange,提问作者RedLeu
相关产品推荐
相关产品推荐

