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

Bash脚本:计算文件中的唯一行数 情况:,bash,Bash,我有一个大文件(数百万行),包含几个小时网络捕获的IP地址和端口,每行一个IP/端口。行的格式如下: ip.ad.dre.ss[:port] 预期结果: 我在记录时收到的每个数据包都有一个条目,因此有很多重复的地址。我希望能够通过某种shell脚本来运行它,这种脚本能够将它简化为格式行 ip.ad.dre.ss[:port] count 其中,count是该特定地址(和端口)的出现次数。不需要做特殊的工作,将不同的端口视为不同的地址 到目前为止,我正在使用此命令从日志文件中刮取所有ip地址:

我有一个大文件(数百万行),包含几个小时网络捕获的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

我不知道如何使用sort聚合行计数。

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

sort ips.txt | uniq -c
要在顶部获得最频繁的结果(感谢Peter Jaric):

要计算唯一行的总数(即不考虑重复行),我们可以使用
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

这是获得重复行数的最快方法,并将重复行按最少频率到最多频率进行排序:

awk '{!seen[$0]++}END{for (i in seen) print seen[i], i}' ips.txt | sort -n
如果您不关心性能,并且希望更容易记住,那么只需运行:

sort ips.txt | uniq -c | sort -n
附言:


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

我喜欢
-bgr
恰巧看起来像是
更大的
的助记符,这是我们在顶部想要的。作为
.bashrc
bash\u别名文件的一个小函数:
函数countuniquelines(){sort“$1”| uniq-c | sort-bgr;}
。调用
countuniquelines myfile.txt
。不确定为什么不
sort-nr
。有趣。可能会对巨大的数据集产生明显的影响
中的
{!seen[$0]+}
在这里是多余的,因为我们只在
末尾进行打印。
sort ips.txt | uniq -c | sort -n