Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 简单读取列和求和第三列_Bash_Awk - Fatal编程技术网

Bash 简单读取列和求和第三列

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

我真的被这件事缠住了,如果有任何帮助,我将不胜感激

我有一个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    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{…}