如何编写shell脚本计算预算文件的产品月度总和及总计并处理异常?
预算统计Shell脚本实现方案
需求说明
我们有一份预算数据文件,需要实现以下统计逻辑:
- 为每行数据追加当月各产品金额总和列
- 最后一行输出所有数据的总计数
实现要求
- 脚本需接收文件名作为位置参数,不允许硬编码文件名
- 所有计算结果直接输出到屏幕
- 任意环节出现错误(文件不存在、数据格式非法等)需打印错误信息后立即终止运行
原有代码问题
你提供的基础脚本存在两个不符合要求的问题:
- 采用交互式输入文件名,不符合参数传入的要求
- 仅打印文件原始内容,没有实现计算逻辑、错误校验能力
完善后的完整脚本
#!/bin/bash # 校验传入参数数量 if [ $# -ne 1 ]; then echo "错误:请传入一个数据文件作为参数,用法:$0 文件名" >&2 exit 1 fi file="$1" # 校验文件合法性 if [ ! -f "$file" ]; then echo "错误:文件 $file 不存在或不是普通文件" >&2 exit 1 fi if [ ! -r "$file" ]; then echo "错误:文件 $file 无读取权限" >&2 exit 1 fi # 使用awk完成计算逻辑 awk ' # 处理表头行 NR == 1 { printf "%s 总和\n", $0 next } # 记录首行数据的字段数,用于后续校验 NR == 2 { expected_cols = NF } # 校验每行字段数是否一致 { if (NF != expected_cols) { print "错误:第"NR"行字段数量不匹配,预期"expected_cols"个字段,实际"NF"个" > "/dev/stderr" exit 1 } line_sum = 0 # 从第2列开始遍历数值列,第1列为产品名称 for (i = 2; i <= NF; i++) { # 校验是否为合法数值(支持整数和小数) if ($i !~ /^[0-9]+(\.[0-9]+)?$/) { print "错误:第"NR"行第"i"列值为"$i",不是合法数值" > "/dev/stderr" exit 1 } line_sum += $i } # 累计总计数 total += line_sum # 输出当前行+总和 printf "%s %.2f\n", $0, line_sum } # 最后输出总计行 END { printf "总计 %.2f\n", total } ' "$file" # 校验awk执行结果,如果出错就终止 if [ $? -ne 0 ]; then exit 1 fi
使用说明
将脚本保存为cal_budget.sh,赋予执行权限后使用:
chmod +x cal_budget.sh ./cal_budget.sh budget.txt
适配说明
如果你的数据列分隔符不是空格,是逗号/制表符等,可以在awk的BEGIN块中添加FS=","(逗号分隔)或FS="\t"(制表符分隔)即可。如果不需要保留两位小数,把输出格式里的%.2f改成%d(整数)即可。
内容的提问来源于stack exchange,提问作者Aktar
相关产品推荐
相关产品推荐

