示例说明
awk 是处理分隔文本的原生方案:-F 设分隔符后每行自动拆成 $1 $2 字段,关联数组按任意键聚合——orders[region] 的键是区域字符串,分组逻辑零成本。NR 排除表头是 CSV 的常规处理。END 块在输入耗尽后执行,报表输出与聚合累积天然分离。
技术要点
- 关联数组按字符串键分组聚合
- END 块输出与累积阶段分离
- 条件过滤前置在同一表达式中
代码解读
aggregate 的主块对每行累加三个数组的对应项;END 遍历数组输出各区域的订单、营收与均单价,printf 的格式符对齐列宽;total_orders 独立累计无分组的全局和。第二个管道演示字段抽取接 sort 排序的流水线;第三个把过滤条件直接写进主块,一行代码完成过滤加聚合。
使用建议
含引号内逗号的真实 CSV 需 gawk 的 FPAT 或专门解析器。数字字段要校验非空防字符串拼接。大文件 awk 单遍特性优于反复 sort。
代码示例
#!/usr/bin/env bash
set -euo pipefail
# 输入形态:region,channel,orders,revenue_cents
readonly SAMPLE='eu,web,120,450000
eu,mobile,80,290000
na,web,95,310000
na,mobile,45,150000
apac,web,30,90000'
# 单遍聚合:分组求和与计数
aggregate() {
awk -F',' '
NR > 1 {
orders[$1] += $3
revenue[$1] += $4
count[$1] += 1
total_orders += $3
}
END {
for (region in orders) {
printf "%-6s 订单 %6d 营收 %10d 均单价 %8.0f\n", \
region, orders[region], revenue[region], \
revenue[region] / orders[region]
}
printf "TOTAL 订单 %6d\n", total_orders
}
'
}
echo "$SAMPLE" | aggregate
# 流式管道形态:配合 sort 输出前 N
echo "$SAMPLE" | awk -F',' 'NR > 1 { print $1, $4 }' \
| sort -k2,2nr \
| head -3
# 条件过滤加聚合一步完成
echo "$SAMPLE" | awk -F',' '$3 >= 80 { sum += $4; n++ }
END { if (n > 0) printf "大渠道合计营收: %d(%d 个)\n", sum, n }'