Linux Shell 中循环不自动汇总,需用变量累加后循环外输出,或用 awk 的 END 块、数组、临时文件、函数等方式实现结束时自动汇总。

在 Linux Shell 中,循环本身不自动汇总,但可以通过变量累积 + 循环外输出的方式实现“结束时自动汇总”。关键在于把统计逻辑放在循环体内更新变量,最后在循环外一次性打印结果。
用 shell 变量做累加器
最常用也最轻量的方式是定义一个初始为 0 的变量,在 for 或 while 循环中持续更新它:
- 统计匹配行数:count=0; for f in *.log; do count=$((count + $(grep -c "ERROR" "$f"))); done; echo "总计 ERROR 行数: $count"
- 统计文件总大小(字节数):total=0; for f in *.txt; do [[ -f "$f" ]] && total=$((total + $(stat -c "%s" "$f" 2>/dev/null))); done; echo "总字节数: $total"
- 注意:每次赋值用 $((...)) 进行算术运算,避免字符串拼接错误
用 awk 在单次扫描中完成汇总
如果数据来自文件或命令输出,直接交给 awk 处理更高效、更可靠,无需显式写循环:
- 统计所有 .conf 文件中注释行总数:find /etc -name "*.conf" -exec cat {} ; 2>/dev/null | awk '/^\s*#/ {c++} END {print "注释行总数:", c+0}'
- 按用户统计进程数并排序:ps -eo user= | awk '{u[$1]++} END {for (i in u) print u[i], i}' | sort -nr
- awk 的 END 块天然就是“循环结束后执行”,适合聚合类统计
用数组或临时文件暂存中间结果
当需要保留明细再汇总(比如分组计数、求平均、找最大值),可用关联数组或临时文件过渡:
- 统计各状态码出现次数(Nginx 日志示例):awk '{code[$9]++} END {for (c in code) print c, code[c]}' access.log | sort -n
- 若需跨多轮循环保持状态,可写入临时文件:tmp=$(mktemp); for f in *.csv; do tail -n +2 "$f" | wc -l >> "$tmp"; done; awk '{s+=$1} END{print "总数据行:", s}' "$tmp"; rm "$tmp"
封装成函数让汇总更清晰
把初始化、累加、输出打包成函数,逻辑一目了然,也方便复用:
- sum_log_errors() { local total=0; for f; do total=$((total + $(grep -c "ERR" "$f" 2>/dev/null))); done; echo "共 $total 处 ERR"
- 调用:sum_log_errors /var/log/app/*.log
- 函数参数用 $@ 接收,避免硬编码路径,提升健壮性











