解决单位不一致问题:提取pcap文件中按总字节数降序排列的Top 5 TCP/UDP流
解决单位不一致问题:提取pcap文件中按总字节数降序排列的Top 5 TCP/UDP流
我来帮你解决这个因为字节单位(kB/bytes)不统一导致排序失效的问题,这里有两种实用的方案,你可以根据自己的使用习惯选择:
方案一:改进现有脚本,统一单位后排序
你的原始思路没问题,只是缺了单位转换的步骤。我们可以用awk解析tshark的输出,把所有总字节数转换成统一的字节数值,再以此为依据排序,最后还原输出格式:
tshark -r test.pcap -q -z conv,tcp | sed '1,5d' | head -n -1 | awk ' { # 识别总字节的单位,转换成纯字节数 if ($9 == "kB") { total_bytes = $8 * 1024 } else if ($9 == "bytes") { total_bytes = $8 } # 把转换后的字节数放在行首,作为排序键 print total_bytes, $0 }' | sort -nr | head -n 5 | cut -d' ' -f2-
步骤说明:
- 还是用你原来的
sed和head去掉tshark输出的表头和末尾汇总行 - 用
awk判断总字节的单位(第9个字段),把kB转换成字节(乘以1024),bytes则直接保留数值 - 将转换后的纯字节数放在每一行的最前面,方便
sort按数值降序排序 - 取排序后的前5行,再用
cut去掉前面的排序键,还原成你熟悉的输出格式
如果要提取UDP流,只需要把-z conv,tcp改成-z conv,udp即可。
方案二:直接从原始包提取数据,避免单位问题
如果不想处理tshark统计输出的单位格式,我们可以直接从原始数据包中提取字段,用awk手动聚合计算每个流的总字节数,这样完全绕开单位转换的麻烦:
tshark -r test.pcap -T fields -e tcp.stream -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e frame.len | awk ' { # 统一流的标识格式(双向流合并,避免源/目标方向不同导致重复统计) if ($2 ":" $3 < $4 ":" $5) { flow = $2 ":" $3 " <-> " $4 ":" $5 } else { flow = $4 ":" $5 " <-> " $2 ":" $3 } # 累加每个流的总字节数和包数 total_bytes[flow] += $6 packet_count[flow] += 1 } END { # 输出总字节数、包数、流信息,方便排序 for (flow in total_bytes) { print total_bytes[flow], packet_count[flow], flow } }' | sort -nr | head -n 5 | awk '{ # 格式化输出成易读的格式(可选,可根据需求调整) kb = int($1 / 1024) bytes = $1 % 1024 byte_str = kb " kB" if (bytes > 0) byte_str = byte_str " " bytes " bytes" print $3, $4, $5, $2, byte_str }'
步骤说明:
- 用
tshark提取每个TCP包的流ID、源IP、源端口、目标IP、目标端口、帧长度 - 用
awk把双向流合并成同一个标识(比如A:port <-> B:port和B:port <-> A:port视为同一个流) - 累加每个流的总字节数和包数
- 按总字节数降序排序,取前5行,最后格式化输出成易读的格式
如果要处理UDP流,只需要把字段中的tcp换成udp:-e udp.stream -e udp.srcport -e udp.dstport。
这两种方案都能解决单位不一致导致的排序错误问题,方案一更贴近你原来的操作习惯,方案二则更灵活可控,完全避免了tshark统计输出的格式限制。
备注:内容来源于stack exchange,提问作者Trevor Philip
相关产品推荐
相关产品推荐

