使用 shellscript 计算列的总和

使用 shellscript 计算列的总和

我有一个 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删除每行中非数字或逗号的所有内容,然后打印新的第二列的值,其中列被视为由一个或多个逗号分隔。和BEGINEND使数据按照dc预期的格式工作。


我使用它是dc因为我不知道是否awk可以充当通用、任意精度的计算器。如果是这样,您可以这样做:

awk -F ',,*' '(NR > 1){ gsub("[^0-9,]",""); SUM_SALARY += $2 } END { print SUM_SALARY }' < text.csv

这种情况的工作方式与前一种情况非常相似,只不过是awk进行算术而不是dc。这还使用-F开关来设置字段分隔符,以避免出现未使用的BEGIN块。

相关内容