在 awk 中求和时缺少值

在 awk 中求和时缺少值

我有两列文件,第一列已排序,例如

0 107
1 1
1 141
2 22
3 1
3 222
4 65
5 1
5 53
6 79

我想要一个输出,第一列中没有重复的条目,第二列是重复的第一列值的第二列旧值的总和。我的尝试:awk '$1 != p{ if (NR>1) print p, s; p=$1; s=0} {s+=$2} END{print p, s}',输出

 107
1 142
2 22
3 223
4 65
5 54
6 79

也就是说,0第一行第一列的值没有显示出来。我遗漏了什么?最好有一行解决方案。

答案1

首先,我建议将 if 子句操作括在括号中。例如,下面很明显 if 子句仅适用于{print p,s},而不适用于p=$1and s=0

awk '$1!=p{if(NR>1){print p,s};p=$1;s=0}{s+=$2}END{print p,s}'

虽然这只是表面上的,但不是一个错误。

你的错误在于没有注意到在比较中,未设置的变量将被视为0和空字符串。对于文件的第一行,$1=0。因此,$1!=p错误的对于第一行(因为p未设置),这意味着p当 awk 开始读取第二行时仍然未设置。

p一个可能的解决方案是在程序启动时设置为空字符串:

awk 'BEGIN{p=""}$1!=p{if(NR>1){print p,s};p=$1;s=0}{s+=$2}END{print p,s}' file
awk '$1!=p{if(NR>1){print p,s};p=$1;s=0}{s+=$2}END{print p,s}' p="" file

现在,$1!=p比较的是真的对于第一行,如0!=""

输出:

0 107
1 142
2 22
3 223
4 65
5 54
6 79

答案2

尝试:

awk '$1 != p && NR>1{print p, s; s=0} {p=$1; s+=$2} END{print p, s}'

怎么运行的

任何时候我们到达序列的末尾,$1 != p && NR>1我们都会打印p, s并重置s回零。

对于每一行,我们将其设置为第一列,然后按第二列p递增。s

在最后一行之后,我们打印p, s

相关内容