You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

文本能否执行两次排序?如何不重复解析源数据对awk输出按不同键排序

双维度流量排序内存实现方案

核心思路

仅需解析一次源数据,将awk统计完成的结果在内存中分发到两个独立的排序流程即可,不需要生成临时文件,有两种原生Bash实现方案可选。

方案1:流式并行处理(性能最优)

利用tee配合Bash进程替换特性,流式处理统计结果,不需要将全量统计结果加载到shell变量中,适合统计条目量较大的场景:

zgrep ^1 20211014T00*.gz \
  | awk '{print $3,$11,$6,$(NF-7)}' \
  | awk 'NR>1{key=$1 " " $2; bytesDown[key]+=$3; bytesUp[key]+=$4} END {for(i in bytesDown) print bytesDown[i], bytesUp[i], i}' \
  | tee >(echo -e "=== 下行流量TOP ==="; sort -rnk1 | head) >(echo -e "\n=== 上行流量TOP ==="; sort -rnk2 | head) > /dev/null

说明:

  • 全程通过内核匿名管道传输数据,无任何磁盘IO,所有处理都在内存中完成
  • 两个排序流程并行执行,性能高于串行处理
  • 最后加> /dev/null是为了丢弃tee的默认标准输出,避免原始统计内容重复打印

方案2:变量缓存(逻辑更直观,输出顺序固定)

如果担心并行处理导致上下行输出顺序混乱,可以先把统计结果缓存到shell变量中,再串行执行两次排序:

# 单次解析源数据,缓存统计结果到变量
stat_result=$(zgrep ^1 20211014T00*.gz \
  | awk '{print $3,$11,$6,$(NF-7)}' \
  | awk 'NR>1{key=$1 " " $2; bytesDown[key]+=$3; bytesUp[key]+=$4} END {for(i in bytesDown) print bytesDown[i], bytesUp[i], i}')

# 按下行排序输出
echo "=== 下行流量TOP ==="
echo "$stat_result" | sort -rnk1 | head

# 按上行排序输出
echo -e "\n=== 上行流量TOP ==="
echo "$stat_result" | sort -rnk2 | head

说明:

  • 逻辑简单易懂,输出顺序完全可控
  • 4GB内存的环境完全可以承载常规日志的统计结果,即使是百万级的流量条目也不会出现内存不足问题

兼容性提示

两种方案都仅依赖Bash原生特性,无需额外安装工具,如果你执行时遇到语法报错,确认当前使用的是bash而非sh/dash即可,执行echo $SHELL可查看当前使用的shell类型。

内容的提问来源于stack exchange,提问作者imac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:27:07