如何在gawk中使用多个通行证?

如何在gawk中使用多个通行证?,awk,gawk,Awk,Gawk,我正在尝试使用CYGWIN的GAWK来处理csv文件。Pass 1查找最大值,Pass 2打印与最大值匹配的记录。我正在使用一个.awk文件作为输入。当我使用手册中的文本时,它在两个过程中都匹配。我可以使用IF表单作为解决方法,但这迫使我在每个模式匹配中使用IF,这是一种痛苦。知道我做错了什么吗 这是我的.awk文件: pass == 1 { print "pass1 is", pass; } pass == 2 { if(pass == 2) print "pas

我正在尝试使用CYGWIN的GAWK来处理csv文件。Pass 1查找最大值,Pass 2打印与最大值匹配的记录。我正在使用一个.awk文件作为输入。当我使用手册中的文本时,它在两个过程中都匹配。我可以使用IF表单作为解决方法,但这迫使我在每个模式匹配中使用IF,这是一种痛苦。知道我做错了什么吗

这是我的.awk文件:

pass == 1
{
    print "pass1 is", pass;  
}    

pass == 2
{
if(pass == 2)
    print "pass2 is", pass;  
}    
这是我的输出(输入文件只是“hello”):

这是我的命令行:

gawk -F , -f test.awk pass=1 x.txt pass=2 x.txt
非常感谢您的帮助。

一个(g)awk解决方案可能是这样的:

awk 'FNR == NR{print "1st pass"; next}
     {print "second pass"}' x.txt x.txt
(如有必要,请将
awk
替换为
gawk

比方说,您希望在文件
x.txt
的第一列中搜索最大值,然后打印第一列中具有该值的所有行,您的程序可能如下所示(感谢Ed Morton提供的一些提示,请参阅注释):

x.txt的输出:

6,5
2,6
5,7
6,9


这是如何工作的?变量
NR
随着每条记录的增加而不断增加,而
FNR
在读取新文件时被重置为
1
。因此,
FNR==NR
仅对处理的第一个文件有效。

因此……F.Knorr准确而简洁地回答了你的问题,他应该得到一个绿色的大复选标记。
NR==FNR
正是您要寻找的秘方

但这里有一种不同的方法,以防多通道的事情被证明是有问题的。(也许你是从慢速驱动器、U盘、网络、DAT磁带等读取文件。)


awk-F,'$1>m{delete l;n=0;m=$1}m==1{l[++n]=$0}END{for(i=1;i这里的问题是换行符对awk很重要

# This does what I should have done: 
pass==1 {print "pass1 is", pass;} 
pass==2 {if (pass==2) print "pass2 is", pass;}

# This is the code in my question:
# When pass == 1, do nothing
pass==1 
# On every condition, do this
    {print "pass1 is", pass;} 
# When pass == 2, do nothing
pass==2 
# On every condition, do this
    {if (pass==2) print "pass2 is", pass;}

使用pass==1,pass==2并没有那么优雅,但它可以工作。

@MarkSetchell:你是对的,括号是没有必要的。因此,我更新了我的答案。然而,对于像我这样习惯于Java/C的人来说……包含条件的括号更为熟悉。
(条件){code block}
。该脚本中没有特定于gawk的内容。为了避免要求max>=0,并使脚本可移植到所有AWK(某些AWK在某些情况下使用未细化的三元表达式会失败)并且更易于阅读,请将测试更改为
FNR==NR{max=((FNR==1)| |($1>max)$1:max);下一步}
。任何时候进行最小值或最大值计算时,请使用读取的第一个值进行种子设定,不要使用诸如零之类的随机值进行种子设定。您可以而且应该删除
{print$0}
,因为当条件为真时,这是默认操作。@EdMorton:谢谢您的评论。我已相应地修改了我的答案(也为此向您表示感谢)谢谢你的帮助。我找到了答案。请看下面我的答案。很好,但按照惯例,正如每个awk函数所创建的那样,awk数组(以及字符串字符位置和字段号)从1开始,而不是从0开始,所以只需调整到
list[++n]=$0(i=1;我非常感谢你指出这一点。在我的awk生涯中,我从未想到过这一点。我已经调整了这个答案,但是……现在我必须梳理一小部分其他脚本来进行类似的调整。哇!:-P@EdMorton-哦,最后for循环中的条件也需要更改为
iYeah It当我读到你上面的第一条评论时,但那时编辑我的评论已经太晚了,我想你也会马上发现它。@EdMorton,很抱歉让你回到这一点,但我注意到,声明“通常,数组中的索引必须是非负整数。例如,索引0指定数组中的第一个元素。“这似乎是“nawk”文档中数组简介的直接转录。您是否有任何关于在1开始数组的约定的参考资料?仅供参考GNU awk有一个名为
argid
的变量,它使您的
pass
变量冗余。
6,5
2,6
5,7
6,9
6,5
6,9
awk -F, '$1>m{delete l;n=0;m=$1}m==$1{l[++n]=$0}END{for(i=1;i<=n;i++)print l[i]}' inputfile
BEGIN {
  FS=","
}

$1 > max {
  delete list           # empty the array
  n=0                   # reset the array counter
  max=$1                # set a new max
}

max==$1 {
  list[++n]=$0          # record the line in our array
}

END {
  for(i=1;i<=n;i++) {   # print the array in order of found lines.
    print list[i]
  }
}
# This does what I should have done: 
pass==1 {print "pass1 is", pass;} 
pass==2 {if (pass==2) print "pass2 is", pass;}

# This is the code in my question:
# When pass == 1, do nothing
pass==1 
# On every condition, do this
    {print "pass1 is", pass;} 
# When pass == 2, do nothing
pass==2 
# On every condition, do this
    {if (pass==2) print "pass2 is", pass;}