Bash脚本:计算文件中的唯一行

Wug*_*Wug 111 bash

情况:

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

ip.ad.dre.ss[:port]
Run Code Online (Sandbox Code Playgroud)

期望的结果:

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

ip.ad.dre.ss[:port] count
Run Code Online (Sandbox Code Playgroud)

where count特定地址(和端口)的出现次数.不需要做任何特殊工作,将不同的端口视为不同的地址.

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

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

从那里,我可以使用一个相当简单的正则表达式来清除我的地址发送的所有IP地址(我不关心)

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

sort -u ips.txt > intermediate.txt
Run Code Online (Sandbox Code Playgroud)

我不知道如何通过排序以某种方式聚合行计数.

Mic*_*man 277

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

sort ips.txt | uniq -c
Run Code Online (Sandbox Code Playgroud)

为了获得最频繁的结果(感谢Peter Jaric):

sort ips.txt | uniq -c | sort -bgr
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢`-bgr`巧合地看起来像`更大'的助记符,这就是我们想要的顶部. (7认同)

qwr*_*qwr 13

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

sort ips.txt | uniq | wc -l
awk '!seen[$0]++' ips.txt | wc -l
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Luc*_*ano 6

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

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

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

sort ips.txt | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)

PS:

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