我正在尝试使用CYGWIN中的GAWK来处理csv文件。通过1找到最大值,通过2打印匹配最大值的记录。我正在使用.awk文件作为输入。当我使用手册中的文本时,它在两次传递中都匹配。我可以使用IF形式作为解决方法,但这迫使我在每个模式匹配中使用IF,这是一种痛苦。知道我做错了吗?
这是我的.awk文件:
pass == 1
{
print "pass1 is", pass;
}
pass == 2
{
if(pass == 2)
print "pass2 is", pass;
}
这是我的输出(输入文件只是“你好”):
hello
pass1 is 1
pass1 is 2
hello
pass2 is 2
这是我的命令行:
gawk -F , -f test.awk pass=1 x.txt pass=2 x.txt
我很感激任何帮助。
答案 0 :(得分:6)
(g)awk解决方案可能如下所示:
awk
(如有必要,请gawk
替换x.txt
。)
假设您要搜索文件awk -F"," 'FNR==NR {max = ( (FNR==1) || ($1 > max) ? $1 : max ); next}
$1==max' x.txt x.txt
的第一列中的最大值,然后在第一列中打印具有此值的所有行,您的程序可能如下所示(感谢 Ed Morton < / em>有些提示,请参阅评论):
x.txt
6,5
2,6
5,7
6,9
的输出:
6,5
6,9
是
NR
这是如何工作的?变量FNR
随着每条记录而不断增加,而1
在读取新文件时会重置为FNR==NR
。因此,{{1}}仅适用于处理的第一个文件。
答案 1 :(得分:3)
所以...... F.Knorr准确而简洁地回答了你的问题,他应该得到一个很大的绿色标记。 NR==FNR
正是您正在寻找的秘密酱。
但是,这是一种不同的方法,以防万一事件被证明是有问题的。 (也许你正在从慢速驱动器,USB记忆棒,网络,DAT磁带等中读取文件。)
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]
}
}
使用F.Knorr测试的相同输入数据,我得到相同的结果。
这里的想法是在一遍中浏览文件。我们在数组中记录与最大值匹配的每一行,如果我们遇到超过最大值的值,我们清除数组并重新开始收集行。
这种方法在CPU和内存上占主导地位(取决于数据集的大小),但是单次通过时,它可能在IO上更轻。
答案 2 :(得分:0)
这里的问题是换行符对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并不优雅,但它可以工作。