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. Koa源码解析

    Koa是一款设计优雅的轻量级Node.js框架,它主要提供了一套巧妙的中间件机制与简练的API封装,因此源码阅读起来也十分轻松,不论你从事前端或是后端研发,相信都会有所收获. 目录结构 首先将源码下载 ...

  2. mysql命令行创建数据库

    create database publiccms; grant all privileges on publiccms.* to root@localhost identified by 'publ ...

  3. Ansible Playbooks入门介绍

    1.目录结构 2.详细目录 3.主任务文件main.yaml 主任务文件main.yaml - name: print server name and user to remote testbox # ...

  4. 如何设置hyper-v下的ubuntu虚拟机分辨率

    1.登陆ubuntu虚拟机 2.vi /etc/default/grub,改变如下内容: 改变前: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" ...

  5. [BZOJ2091]The Minima Game

    Description 给出N个正整数,AB两个人轮流取数,A先取.每次可以取任意多个数,直到N个数都被取走.每次获得的得分为取的数中的最小值,A和B的策略都是尽可能使得自己的得分减去对手的得分更大. ...

  6. servlet初始化参数

    使用<context-param>标签初始化的参数是被应用程序中所有的servlet所共享.但是有时候我们需要为某一个特定的servlet配置参数,这个时候我们就需要使用servlet初始 ...

  7. UOJ34 多项式乘法(NTT)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. centos7 VNC安装

    root用户: yum install tigervnc-server .service vim /etc/systemd/system/vncserver@:.service .service vn ...

  9. vue-router的一个小实例

    非2.0的 vue2.0还有vue-router2.0的改变还是挺大的 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基于 ...

  10. 运行UART的程序

    1 捎程序的时候,注意,捎入的是norflash,此时的按钮应该在norFlash.2 当捎入成功的时候,开始运行程序时,应该把按钮按回nandflash,因为程序的启动就是在nandflash,他把 ...