我真的非常坚持这一点,并感谢任何帮助!
我有一个3列的CSV文件。如果一行具有相同的第一列和第二列作为另一行,则将这些行中的第三列添加在一起。
Input:
7514 128 1
7514 128 2
7514 128 1
7514 544 1
7514 544 3
5807 338 4
5807 338 1
Output:
7514 128 4
7514 544 4
5807 338 5
我试过
awk '{A[$1]+=$2;next}END{for(i in A){print i,A[i]}}' file
但它只给了我
7514 1472
5807 676
这不是我想要的。非常感谢任何awk专家对此的帮助。
答案 0 :(得分:4)
我相信你想要这样的东西:
awk '{A[$1" "$2]+=$3}END{for(i in A){print i,A[i]}}' file
(你真的不需要next
),如以下成绩单所示:
$ echo '7514 128 1
7514 128 2
7514 128 1
7514 544 1
7514 544 3
5807 338 4
5807 338 1' | awk '{A[$1" "$2]+=$3}END{for(i in A){print i,A[i]}}'
7514 128 4
5807 338 5
7514 544 4
您的原始代码根据第1列中的键对第2列求和。
您需要执行的操作(以及上述awk
脚本所做的)是根据 1和2 列创建的键对 3 列进行求和。
而且,如果数据总是被排序并且可能有批次的密钥(超出awk
可以处理的范围),您只需使用:
awk 'NR==1 {last=$1" "$2; sum=$3; next}
last!=$1" "$2 {print last" "sum; last=$1" "$2; sum=0}
{sum += $3}
END {print last" "sum}'
这是你的经典"排序列表处理。
它没有数组存储解决方案那么优雅,所以如果数组超出awk
的容量,那么应该只使用。我只是为了完整性而加入它。
答案 1 :(得分:1)
Pure Bash:
declare -A sum # an associative array
while read k1 k2 val ; do
((sum[$k1-$k2]+=val)) # combine keys to one
done < "$infile"
for k in ${!sum[*]}; do
echo -e "${k/-/ } ${sum[$k]}" # separate keys
done
输出:
7514 544 4
7514 128 4
5807 338 5