【问题标题】:Bash Script: count unique lines in fileBash Script:计算文件中的唯一行
【发布时间】:2013-04-05 18:01:59
【问题描述】:

情况:

我有一个大文件(数百万行),其中包含来自几个小时网络捕获的 IP 地址和端口,每行一个 ip/端口。行的格式如下:

ip.ad.dre.ss[:port]

想要的结果:

我在记录时收到的每个数据包都有一个条目,因此有很多重复的地址。我希望能够通过某种 shell 脚本来运行它,该脚本能够将其减少为格式的行

ip.ad.dre.ss[:port] count

其中count 是该特定地址(和端口)的出现次数。不用做特别的工作,把不同的端口当作不同的地址。

到目前为止,我正在使用此命令从日志文件中抓取所有 IP 地址:

grep -o -E [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)? ip_traffic-1.log > ips.txt

由此,我可以使用一个相当简单的正则表达式来刮掉我的地址发送的所有 IP 地址(我不在乎)

然后我可以使用以下内容提取唯一条目:

sort -u ips.txt > intermediate.txt

我不知道如何通过排序以某种方式汇总行数。

【问题讨论】:

    标签: bash


    【解决方案1】:

    您可以使用uniq 命令获取已排序的重复行数:

    sort ips.txt | uniq -c
    

    为了获得最常见的结果(感谢 Peter Jaric):

    sort ips.txt | uniq -c | sort -bgr
    

    【讨论】:

    • 我喜欢 -bgr 巧合地看起来像 bigger 的助记符,这正是我们想要的顶部。
    • 作为.bashrc.bash_aliases 文件的一个小功能:function countuniquelines () { sort "$1" | uniq -c | sort -bgr; }。致电countuniquelines myfile.txt
    • 不知道为什么不sort -nr
    【解决方案2】:

    计算唯一行的总数(即不考虑重复行),我们可以使用uniq 或带有wc 的Awk:

    sort ips.txt | uniq | wc -l
    awk '!seen[$0]++' ips.txt | wc -l
    

    Awk 的数组是关联的,因此它的运行速度可能比排序快一点。

    生成文本文件:

    $  for i in {1..100000}; do echo $RANDOM; done > random.txt
    $ time sort random.txt | uniq | wc -l
    31175
    
    real    0m1.193s
    user    0m0.701s
    sys     0m0.388s
    
    $ time awk '!seen[$0]++' random.txt | wc -l
    31175
    
    real    0m0.675s
    user    0m0.108s
    sys     0m0.171s
    

    【讨论】:

    • 有趣。可能会对庞大的数据集产生明显的影响
    【解决方案3】:

    这是获取重复行数并按照最不频繁到最频繁的顺序将它们很好地打印出来的最快方法:

    awk '{!seen[$0]++}END{for (i in seen) print seen[i], i}' ips.txt | sort -n
    

    如果您不关心性能并且想要更容易记住的东西,那么只需运行:

    sort ips.txt | uniq -c | sort -n
    

    PS:

    sort -n 将字段解析为数字,这是正确的,因为我们使用计数进行排序。

    【讨论】:

    • {!seen[$0]++} 中的! 在这里是多余的,因为我们只在END 进行打印。
    • 在我的示例中(3.7GB 文件,187M 行,重复次数很少),两次使用排序最终都更快。不同之处可能是我将语言环境设置为 C(例如,参见 unix.stackexchange.com/questions/87745/what-does-lc-all-c-do)。 LC_ALL=C sort ips.txt | LC_ALL=C uniq -c | LC_ALL=C sort -bgr > ips.out
    猜你喜欢
    • 2019-08-10
    • 1970-01-01
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多