在 Linux下,有两个文件,分别记录了很多 ip 地址,怎么求得在两个文件中都出现的 ip?以及所有的不重复的 ip?

如 a 文件:

1
2
3
4
10.10.1.101
10.10.1.104
10.10.1.102
10.10.1.103

b 文件:

1
2
3
10.10.1.101
10.10.1.105
10.10.1.103

交集(亦即 a,b 中都出现的 ip)

1
sort a b | uniq -d

并集(a,b 中所有的 ip)

1
sort a b | uniq

差集(a-b)

1
sort a b b | uniq -u

相关命令和参数

sort可以将文件进行排序,排序是为了通过管道交接uniq处理,因为uniq命令只能处理相邻的行,sort后面可以接多个文件,表示同时对多个文件进行综合排序。如上面的sort a b,表示同时排序 a,b 两个文件。uniq可以删除文件中重复的行,得到文件中唯一的行,-d参数表示输出出现次数大于1的内容;-u表示输出出现次数为1的内容;

知道上述参数后,求并,交都很easy了。关键是差集,如上,sort a b b,因为用了两个b,因此排序后,结果中,b的ip必然最少出现了两次,再uniq下,剩下的就是a中出现,而b中没出现的ip了。

经常有这样一个需求:从日志中找出访问量最多的前 10 个 IP,并统计次数,日志格式如下:

1
2
3
4
192.168.1.2 - - [01/Sep/2019:00:34:23 +0800] "GET /phpmyadmin/ HTTP/1.1"
192.168.1.5 - - [01/Sep/2019:00:34:23 +0800] "GET /robots.txt HTTP/1.1"
192.168.1.2 - - [01/Sep/2019:00:34:23 +0800] "GET /robots.txt HTTP/1.1"
... 省略

先对第一列做处理,然后用 sort

1
cat log | awk '{print $1}' | sort | uniq -c | sort -nr | head 10