![使用数组进行 awk 比较](https://linux22.com/image/69918/%E4%BD%BF%E7%94%A8%E6%95%B0%E7%BB%84%E8%BF%9B%E8%A1%8C%20awk%20%E6%AF%94%E8%BE%83.png)
我有以下文件:
6180,6180,0,1,,1,0,1,1,0,0,0,0,0,0,0,0,4326,4326,,0.440000,
6553,6553,0,1,,1,0,1,1,0,0,0,0,1,0,1,0,4326,4326,,9.000000,
1297,1297,0,0,,0,0,1,0,0,0,0,0,1,0,1,0,1707,1707,,7.000000,
6598,6598,0,1,,1,0,1,1,0,0,0,1,0,0,0,0,1390,1390,,0.730000,
4673,4673,0,1,,1,0,1,1,0,0,0,0,0,0,0,0,1707,1707,,0.000000,
我需要一个 awk 命令来打印 18 美元的最大值 21 美元。
所需的输出将如下所示:
6553,6553,0,1,,1,0,1,1,0,0,0,0,1,0,1,0,4326,4326,,9.000000,
1297,1297,0,0,,0,0,1,0,0,0,0,0,1,0,1,0,1707,1707,,7.000000,
6598,6598,0,1,,1,0,1,1,0,0,0,1,0,0,0,0,1390,1390,,0.730000,
我得到了这个结果,但是使用排序命令,如下所示:
sort -t, -k18,18n -k21,21nr | awk -F"," '!a[$18]++'
虽然我想用单个 awk 命令来完成它。
请指教,
答案1
我不明白为什么你想用一个awk
命令来完成它,你所拥有的似乎非常好。无论如何,这是一种方法:
$ awk -F, '(max[$18]<$21 || max[$18]==""){max[$18]=$21;line[$18]=$0}
END{for(key in line){print line[key]}}' file
6598,6598,0,1,,1,0,1,1,0,0,0,1,0,0,0,0,1390,1390,,0.730000,
1297,1297,0,0,,0,0,1,0,0,0,0,0,1,0,1,0,1707,1707,,7.000000,
6553,6553,0,1,,1,0,1,1,0,0,0,0,1,0,1,0,4326,4326,,9.000000,
这个想法很简单。我们有两个数组,max
分别$18
作为键和$21
值。对于每一行,如果 保存的值$18
小于$21
或没有存储 的值$18
,则我们将当前行 ( $0
) 作为 的值存储$18
在数组中line
。最后,在END{}
块中,我们打印 array line
。
请注意,上面的脚本将其$18
视为字符串。因此,001
和1
会被视为不同的字符串。
答案2
使用uniq
代替awk
可以更快一点:
sort -t, -k18,18nr -k21,21nr | uniq -s39 -w4
答案3
您可以尝试以下操作awk
:
awk -F"," '{ if (max[$18] < $21) { max[$18] = $21; x[$18] = NR; } z[NR] = $0; } END { for (i in x) print z[x[i]]; }' file
它使用 3 个数组max
,并x
带有列键$18
和z
行号键。我们max
保存最大值,保存x
包含最大值的行数,以及z
文件中的每一行。在END
数组中每个键的块中x
,我们打印 的值z[x[i]]
。
此解决方案不适用于大文件,因为它将整个文件读取到内存中。