Bash 简单读取列和求和第三列
我真的被这件事缠住了,如果有任何帮助,我将不胜感激 我有一个3列CSV文件。如果一行的第1列和第2列与另一行相同,则将这些行中的第3列相加Bash 简单读取列和求和第三列,bash,awk,Bash,Awk,我真的被这件事缠住了,如果有任何帮助,我将不胜感激 我有一个3列CSV文件。如果一行的第1列和第2列与另一行相同,则将这些行中的第3列相加 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
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专家在这方面的帮助。我相信您希望得到这样的帮助:
awk '{A[$1" "$2]+=$3}END{for(i in A){print i,A[i]}}' file
(您实际上不需要下一个
)如以下成绩单所示:
$ 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和列组成的键对列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
的容量时才应该使用它。我只是为了完整性才把它包括进去。我相信你想要这样的东西:
awk '{A[$1" "$2]+=$3}END{for(i in A){print i,A[i]}}' file
(您实际上不需要下一个
)如以下成绩单所示:
$ 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和列组成的键对列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
的容量时才应该使用它。我只是为了完整性才加入它。纯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
纯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
数据是否总是排序?数据是否总是排序?或者可以使用
awk
的多下标功能:awk-vSUBSEP=“”{s[$1,$2]+=$3}END{…}
或者可以使用awk
的多下标功能:awk-vSUBSEP=“”{s[$1,$2]+=$3}END{…}