Awk-基于susbtring的特定行的和字段

Awk-基于susbtring的特定行的和字段,awk,sum,field,line,Awk,Sum,Field,Line,我有一个文件,看起来像: 100001001 0 130 100001001 0 610 100001001 0 210 100001001 0 100 100001001 1 80 100001002 0 300 100001002 0 200 100001002 0 100 100001003 0 200 100001003 0 100 100001004 1 50 我想对每个相同的第一个字段的第三个字段求和,并排除第二个字段中包含1的行,输出如下: 100001001 1050 10

我有一个文件,看起来像:

100001001 0 130
100001001 0 610
100001001 0 210
100001001 0 100
100001001 1  80
100001002 0 300
100001002 0 200
100001002 0 100
100001003 0 200
100001003 0 100
100001004 1  50
我想对每个相同的第一个字段的第三个字段求和,并排除第二个字段中包含1的行,输出如下:

100001001 1050
100001002  600
100001003  300
到目前为止,我所使用的命令由于某种原因似乎不起作用,有人能帮助我吗

awk ' $2 != 1 { sum[$1] += $3 }' 

这一行应该有助于:

 awk '$2!=1{a[$1]+=$3}END{for(x in a)print x, a[x]}' file

代码中的问题是,在数组中求和后没有打印输出。

这一行代码应该有帮助:

 awk '$2!=1{a[$1]+=$3}END{for(x in a)print x, a[x]}' file

代码中的问题是,在数组中求和后没有打印输出。

尝试一下这个测试:

awk '{ if (NR==1) {sum=0} else if (lastid!=$1) {printf("%s %s\n", lastid, sum); sum=0} if ($2!=1) {sum+=$3} lastid=$1} END{if (sum>0) print lastid, sum}' afile

假设第一列已排序。

尝试一下这个测试列:

awk '{ if (NR==1) {sum=0} else if (lastid!=$1) {printf("%s %s\n", lastid, sum); sum=0} if ($2!=1) {sum+=$3} lastid=$1} END{if (sum>0) print lastid, sum}' afile

假定第一列被排序。

AWK不是C。你当前使用AWK所做的事情就像是在使用C++,而只使用程序编程,而只是C++中的C语言的子集——它缺少了语言的点/好处。如果您想学习如何习惯地使用Awk,请参阅并阅读Arnold Robbins的《有效的Awk编程》,第四版。@EdMorton Waou!非常感谢。这不是一个惯用的版本,但已经过测试。我会仔细阅读这本书。不,不是这样,当键发生变化时打印,最终是一种非常合理和常见的方法,带有排序键。结尾部分是必要的,顺便说一句-您的代码只生成预期的输出,因为最后一个输入行的$2==1。它主要不是使用awk默认变量值和内置的{}结构,而是像在C中那样编写{if{}}。您的方法将用习惯用法awk编写为awk'$2==1{next}lastid=$1{如果NR>1打印lastid,sum;lastid=$1;sum=0}{sum+=$3}结束{print lastid,sum}'file@EdMorton格洛普!答案将被编辑,以修复错误。正如您所猜测的,它仅通过示例进行了测试。我还将测试这个新的惯用版本。谢谢!我已经在没有初始化的情况下使用了一个变量来查看发生了什么,但我通常不会这样做,因为我根本不知道这些默认值。读完这本书后,我可能会有更多的问题。仅供参考,所有awk标量变量都是数字字符串类型,并且初始化为零或空值。它们以后会根据第一次使用它们的上下文变成数字或字符串。所有数组都包含数字字符串内容,但所有数组索引都是字符串没有歧义,不要认为[3]=foo意味着[]有数字索引,因为它没有-在该上下文中,3将转换为3。是的,读那本书是最好的起点——省去了多年的挠头!AWK不是C。你现在用AWK做的事情就像你正在使用C++一样,只是使用了程序化编程,而C++的构造子集只存在于C中,它缺少了语言的点/好处。如果您想学习如何习惯地使用Awk,请参阅并阅读Arnold Robbins的《有效的Awk编程》,第四版。@EdMorton Waou!非常感谢。这不是一个惯用的版本,但已经过测试。我会仔细阅读这本书。不,不是这样,当键发生变化时打印,最终是一种非常合理和常见的方法,带有排序键。结尾部分是必要的,顺便说一句-您的代码只生成预期的输出,因为最后一个输入行的$2==1。它主要不是使用awk默认变量值和内置的{}结构,而是像在C中那样编写{if{}}。您的方法将用习惯用法awk编写为awk'$2==1{next}lastid=$1{如果NR>1打印lastid,sum;lastid=$1;sum=0}{sum+=$3}结束{print lastid,sum}'file@EdMorton格洛普!答案将被编辑,以修复错误。正如您所猜测的,它仅通过示例进行了测试。我还将测试这个新的惯用版本。谢谢!我已经在没有初始化的情况下使用了一个变量来查看发生了什么,但我通常不会这样做,因为我根本不知道这些默认值。读完这本书后,我可能会有更多的问题。仅供参考,所有awk标量变量都是数字字符串类型,并且初始化为零或空值。它们以后会根据第一次使用它们的上下文变成数字或字符串。所有数组都包含数字字符串内容,但所有数组索引都是字符串没有歧义,不要认为[3]=foo意味着[]有数字索引,因为它没有-在该上下文中,3将转换为3。是的,读那本书是最好的起点——省去了多年的挠头!