![计算 2 行块的 uniq 实例](https://linux22.com/image/123712/%E8%AE%A1%E7%AE%97%202%20%E8%A1%8C%E5%9D%97%E7%9A%84%20uniq%20%E5%AE%9E%E4%BE%8B.png)
给定输入:
144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
我怎样才能输出:
144.252.36.69
afrloop=32235330165603 3 times
222.252.36.69
afrloop=31135330165603 4 times
答案1
paste - - < file | sort | uniq -c
答案2
awk
如果您想要自定义输出格式,这是一个解决方案
NR%2==1 {ip=$0; next}
NR%2==0 {a[ip"\n"$0]++}
END {
for(i in a)
printf "%s %d times\n", i, a[i]
}
该脚本可以执行为
awk -f main.awk file
解释
首先,我们用来
NR%2==1
匹配奇数行,因为奇数模 2 等于 1,如果任何行匹配此条件,那么我们将整行保存$0
到名为 的变量中ip
。我们可以用来next
跳过任何进一步的处理并直接进入下一次迭代。其次,我们用来
NR%2==0
匹配偶数行,如果一行匹配,那么我们创建一个标记为ip"\n"$0
数组的索引a
,并增加该特定索引的计数值。例如,等效的展开式如下a["144.252.36.69 afrloop=32235330165603"] += 1
\n
为了简单起见,我忽略了本示例中的新行最后
END
,在处理完每一行后,我们使用循环for
打印出数组内每个元素的值a
,在我们的例子中是每个唯一索引的计数
趣味基准
测试文件生成(100万条记录)
awk ' BEGIN{for(i=1;i<10000000;i++) printf "%d\nafrLoop=%d\n", int(rand()*100), int(rand()*10)} ' > test $ head test 23 afrLoop=2 84 afrLoop=1 58
@n.caillou 糊状溶液
$ time paste - - < test | sort | uniq -c > /dev/null real 0m11.250s user 0m11.352s sys 0m0.272s
awk解决方案
$ time awk -f main.awk test > /dev/null real 0m5.673s user 0m5.636s sys 0m0.036s