![使用 shellscript 计算列的总和](https://linux22.com/image/108092/%E4%BD%BF%E7%94%A8%20shellscript%20%E8%AE%A1%E7%AE%97%E5%88%97%E7%9A%84%E6%80%BB%E5%92%8C.png)
我有一个 csv 文件text.csv
,想计算所有员工的总工资。里面的数据如下:
Id,name,salary,designation
12,joe,thomas,253637,IT,admin
25,miacheal,364829,software engineer
46,mike,silva,adam, 374829479, senior, software, engineer
85,amber johnson,3728291,IT
24,Austin barclay, 3701830,software engineer
我尝试过使用
awk -F "," '{ SUM_SALARY += $3 } END { print SUM_SALARY }'
但总和不正确。真实数据有550万条。
答案1
假设有一个迁移工资字段(从字段 3 到字段 5 并返回),两个 GNUgrep
可以隔离工资,并将它们传递给numsum
:
grep -o '[, ][[:digit:]]*,' test.csv | grep -o '[[:digit:]]*' | numsum
输出:
382878066
答案2
您的name
字段包含逗号但未加引号,因此每行的列awk
中都会看到不同类型的值$3
。即使它们被引用,情况也会如此,但在此处显示的情况下,即使真正的 CSV 解析器也无济于事。这是我为解决这个问题所做的事情:
awk 'BEGIN { FS=",,*"; print 0 }
(NR > 1) { gsub("[^0-9,]",""); printf "%d+\n", $2 }
END { print "pq" }' < text.csv \
| dc
首先用于gsub
删除每行中非数字或逗号的所有内容,然后打印新的第二列的值,其中列被视为由一个或多个逗号分隔。和BEGIN
块END
使数据按照dc
预期的格式工作。
我使用它是dc
因为我不知道是否awk
可以充当通用、任意精度的计算器。如果是这样,您可以这样做:
awk -F ',,*' '(NR > 1){ gsub("[^0-9,]",""); SUM_SALARY += $2 } END { print SUM_SALARY }' < text.csv
这种情况的工作方式与前一种情况非常相似,只不过是awk
进行算术而不是dc
。这还使用-F
开关来设置字段分隔符,以避免出现未使用的BEGIN
块。