Shell 命令行求两个文件每行对比的相同内容

遇到的一个实际问题是,2017年08月01日起,所有未经实名的域名,全部停止解析。而我手上有不少域名,其中很多都是没有实名的。但我不知道哪些实名了,哪些没有实名。所以,我搞到了两个文件:

  1. 我的上级代理商的所有未实名的域名列表
  2. 我的所有域名列表

现在,我需要得到的是,我的域名在所有未实名域名列表中出现的个数。

简单来说,就是求a文件和b文件的每行对比的合集。

两层 while 循环求合集

事实上我解决这个问题是用js解决的。把两个文件构建成数组之后,通过两层循环对比,就输出了我想要的结果。

但这不是学习shell嘛,尝试用同样的思路,用shell解决。

代码如下:

cat b.txt | while read lineb
  do
    cat a.txt | while read linea
      do
      if [ $lineb -eq $linea ]
        then
        echo $lineb
      fi
    done
  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 ]
      then
      echo $i
    fi
  done
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
11
    12
2
        3
4
        5
6
7
        8
9

第一列表示第一个文件独有的内容,第二列表示第二个文件独有的内容,第三列是共有的内容,也就是合集。

OK,我们在修改一下参数,只获取第三列,命令如下:

comm -12 <(sort a.txt|uniq) <(sort b.txt|uniq)

好,输出的内容正是我们想要的。

其他补充

  1. unix思想中,一个程序只做一件事情。而我们把一个内容要进行去重处理,就必须进行两个操作:

    1. 首先进行排序操作 sort
    2. 然后把相邻并且相同的内容给去重 uniq
  2. 当我们不知道一个命令是干嘛的时候,可以用 whatis xxx 来进行查询
  3. whatis 不能满足我们的需求的时候,我们使用 man xxx 来进行更加详细的查看。
  4. 我们写的 *.sh 文件如果希望直接运行,可以用 chmod +x *.sh 来赋予 *.sh 直接运行的权限。之后可以用 ./*.sh 来执行
  5. 如果随便写写,不要求运行权限,可以 sh *.sh 来运行脚本
  6. 这两种运行的结果是有差异的,具体自行参考这里

本文有 FungLeo 原创,允许转载,但转载必须保留首发链接。

Shell 命令行求两个文件每行对比的相同内容的更多相关文章

  1. shell命令之根据字符串查询文件对应行记录

    显示xxx字符串对应的行数,并向前打印3行,向后打印2行,查找对应文件为filename.txt 命令:grep -n 'xxx' -A3 -B2 --color=auto filename.txt ...

  2. 用shell求两个文件的差集

    假设有两个文件a.file和b.file,分别代表集合A和集合B. a.file的内容如下: abcde b.file的内容如下: cdefg 可以用grep命令 grep命令是常用来搜索文本内容的, ...

  3. perl对比两个文件的行

    perl对比两个文件的行 对比两个文件的各行,得到A与B相同的行/A与B不相同的行 主要功能 得到相同行 得到A中包含,B不包含的行 得到B中包含,A中不包含的行 具体执行情况 Perl代码 #!/u ...

  4. LINUX Shell 下求两个文件交集和差集的办法

    http://blog.csdn.net/autofei/article/details/6579320 假设两个文件FILE1和FILE2用集合A和B表示,FILE1内容如下: a b c e d ...

  5. Linux 命令之split(将一个大文件根据行数平均分成若干个小文件)

    把一个 txt 文件导入到 excel 中,但是 excel 单列支持的行数为 1048576,而我需要导入的 txt 文件总共有 7945674 ,我们无法一次性将整个 txt 文件里面的内容导入到 ...

  6. Linux命令(21)查看文件的行数

    在 linux 系统中没有在 windows 系统中那么方便的点点鼠标就可以操作文件了,对文件的各种操作都必须使用各种命令来完成.比如有时候我们需要在不查看文件内容的情况下需要知道该文件有多少行.这个 ...

  7. shell 命令 if [ -d filename] 判断文件

    作者:曹毅涵  [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c FILE ] 如果 FILE 存在且是一个字特殊 ...

  8. C#远程执行Linux系统中Shell命令和SFTP上传文件

    一.工具:SSH.Net 网址:https://github.com/sshnet/SSH.NET 二.调用命令代码: Renci.SshNet.SshClient ssh = "); ss ...

  9. 每天学点Linux命令:倒叙打印文件第二行的前100个大写字母

    sed -n | rev 处理第二行             grep:提取大写字母   o: 不显示非结果  tr:删除换行   Cut:截取1-100个字符  rev:逆序 断断续续搞了好长时间. ...

随机推荐

  1. Android studio通过连接蓝叠模拟器大幅提高速度!

    因为我的电脑是X200,集成显卡,不支持Opengl 2.0,很多安卓模拟器都不能用(夜神.海马玩,mumu等)最后发现蓝叠. 首先WIN+R,CMD,输入ADB,如果没有命令信息,说明我们需要在PA ...

  2. 20145324 《Java程序设计》第8周学习总结

    20145324 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 1.NIO使用频道来衔接数据节点,可以设定缓冲区容量,在缓冲区中对感兴趣的数据区块进行标记,提供clear ...

  3. Linux简单编程学习心得

    在Linux环境下简单编程学习心得 linux编程过程 在上周的<信息安全设计基础>的课程学习中学习到了在虚拟的linux环境下简单的编程.学习过程中接触到了vim.gcc和gcd在实验楼 ...

  4. 回到HTML〇

    HTML(HyperText Markup Language),用来向浏览器标示文档的所有“内容”与“结构”. 抱着温故而知新的态度,在这里通过“回到HTML”系列文章,重新梳理一下HTML的相关知识 ...

  5. codeforces 578c - weekness and poorness - 三分

    2017-08-27 17:24:07 writer:pprp 题意简述: • Codeforces 578C Weakness and poorness• 给定一个序列A• 一个区间的poornes ...

  6. PHP stream相关协议及上下文选项和参数归纳

    支持的协议和封装协议 PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen(). copy(). file_exists() 和 filesize() 的文件系统函数. 除了这些封装协 ...

  7. 实例化后的list的默认值

    public class List默认值 { public static void main(String[] args) { List<String> arrayList = new A ...

  8. git命令速记

    对于不常写代码,有的时候又要提交点代码的人来说,git命令记了又忘,忘了又去花精力记住.有没有一种速记方法,来帮助我们记忆这些玩意呢? 纯属抄袭@_@! 除了几个很基本的命令,复杂一点的,我都要去查, ...

  9. 已知起始点,获取每段等距离途经点的经纬度(用百度js api作)

    已知两个中文地址,自动规划路径,获取路径上每个3公里的点的经纬度 <html> <head> <meta http-equiv="Content-Type&qu ...

  10. jmeter-03 JMeter + Jenkins 集成

    一.准备JMeter 测试计划 mock_api.jmx 接口准备:http://10.1.102.75:8000/mock/api/jmeter 二.jenkins 插件准备  Performanc ...