Shell 命令行求两个文件每行对比的相同内容
Shell 命令行求两个文件每行对比的相同内容
遇到的一个实际问题是,2017年08月01日起,所有未经实名的域名,全部停止解析。而我手上有不少域名,其中很多都是没有实名的。但我不知道哪些实名了,哪些没有实名。所以,我搞到了两个文件:
- 我的上级代理商的所有未实名的域名列表
- 我的所有域名列表
现在,我需要得到的是,我的域名在所有未实名域名列表中出现的个数。
简单来说,就是求a文件和b文件的每行对比的合集。
两层 while 循环求合集
事实上我解决这个问题是用js解决的。把两个文件构建成数组之后,通过两层循环对比,就输出了我想要的结果。
但这不是学习shell嘛,尝试用同样的思路,用shell解决。
代码如下:
cat b.txt | while read lineb
cat a.txt | while read linea
if [ $lineb -eq $linea ]
echo $lineb
done
逻辑非常简单。两层while循环,对比就可以完成了。
两层 for 循环求合集
上面查了一下用
while read
这种方式读取每一行,所以用了
while
这种循环方法。事实上,用
for
循环也一样可以做到,所以,代码如下:
for i in $(cat b.txt); do
for j in $(cat a.txt); do
if [ $j -eq $i ]
echo $i
done
逻辑是一模一样的。
一层 for 循环加 grep 求合集
好了,上面都是逻辑非常简单的处理。那么有没有可能用一层的循环来解决问题呢?
答案是可以的。我们需要用到
grep
这个牛逼的工具。
grep
是一个强大的文本搜索工具,可以匹配正则来进行搜索。
那么逻辑就非常简单了。循环其中一个文件,把每一行的内容利用
grep
正则匹配另一个文件,如果有匹配,则输出。
代码如下:
for i in $(cat b.txt); do
grep "\<$i\>" a.txt
done
循环b文件,并且去搜索一下a文件中是否包含。
因为
grep
命令是把符合的输出出来,所以没必要
echo
一下了。
不用循环求合集
上面的几种方法,都使用了循环来解决问题。都是比较符合我们的编程直觉的。但是,我们可以不可以不使用循环来解决问题呢?
答案是可以的,我找到了一个牛逼的命令
comm
这个命令的解释是
select or reject lines common to two files
,可以用于两个文件之间的比较,它有一些选项可以用来调整输出,以便执行交集、求差、以及差集操作。
好,我们直接上手这个命令试试
comm a.txt b.txt
直接干了一下,发现好像不成。先要排序以及去重才行。
所以,修改命令如下:
comm <(sort a.txt|uniq) <(sort b.txt|uniq)
执行结果如下:
1