计算 2 行块的 uniq 实例

计算 2 行块的 uniq 实例

给定输入:

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
    

相关内容