CSV文件行求和需求及Shell代码无输出问题排查
我有一个包含数字的.csv文件(每行数字用逗号加空格分隔),想要生成一个行数相同、仅含一列的新文件,内容是原文件对应行的数字之和。
输入示例(注意数字间的逗号和空格)
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
预期输出
2
4
5
6
7
我写了下面的代码,但没有任何输出:
file_out="output.txt" file_in="input.txt" cmd3="sum_file=$(awk -F, ' { sum = 0; for (i=1; i<=NF; i++) { sum += $i; } print sum; } ' ${file_in})" echo $cmd3 eval $cmd3
Hey, let's break down why your code isn't producing output and fix it properly. The main issues here are overcomplicating things with eval and not handling the input's comma-plus-space separator correctly.
最简修复:直接用Awk生成输出文件
完全不需要先把结果存到变量里——awk可以一站式完成读取输入、计算求和、写入输出文件的操作。下面是精简后的代码:
file_out="output.txt" file_in="input.txt" # 指定分隔符为逗号加任意数量空格,匹配输入格式 awk -F', *' '{ sum = 0; for (i=1; i<=NF; i++) sum += $i; print sum }' "$file_in" > "$file_out"
关键调整说明:
-F', *': 告诉awk用「逗号+任意数量空格」作为字段分隔符,完美适配你输入里的2, 0格式。就算只用-F,,awk也能自动忽略数字前的空格,但这样写逻辑更清晰。> "$file_out": 把awk的输出直接重定向到目标文件,一步到位得到预期的结果格式。
如果你一定要把结果存在变量里(大文件不推荐)
如果确实需要先把求和结果存到变量中,也完全不需要用eval(这种场景下用eval很容易出问题),直接用命令捕获即可:
file_out="output.txt" file_in="input.txt" # 直接把awk的输出捕获到变量中 sum_file=$(awk -F', *' '{ sum = 0; for (i=1; i<=NF; i++) sum += $i; print sum }' "$file_in") # 将变量内容写入输出文件 echo "$sum_file" > "$file_out"
你的原代码失效的核心原因:当你构建cmd3字符串时,里面的$(awk ...)命令替换会立即执行,sum_file其实在你调用eval之前就已经被赋值了,而且你最后也没有把变量内容写入到输出文件里——就算sum_file有正确数据,也没保存到output.txt中。
内容的提问来源于stack exchange,提问作者Nisba

