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. nmap与Nessus扫描特定靶机分析

    打开装载Metasploitable2虚拟机的靶机,并获取靶机ip: 使用nmap+ip初步扫描靶机 PORT为端口,STATE为端口开放状态,SERVICE为端口的提供的服务.靶机的MAC地址为: ...

  2. left4dead2 常用配置

    难度控制 z_difficulty [Easy, Normal, Hard, Impossible]

  3. vi在行首插入注释符号#

    1.ctrl+v 2.上下键选中要插入的位置 3.按下shift+i,接着输入#符号 4.按键ESC(稍等一下,就会自动插入了)

  4. jsp中获取list长度

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ tag ...

  5. LeetCode——Unique Binary Search Trees II

    Question Given an integer n, generate all structurally unique BST's (binary search trees) that store ...

  6. PAT1071. Speech Patterns (25)

    题目要求的Word定义 Here a "word" is defined as a continuous sequence of alphanumerical characters ...

  7. c++之初级的消息队列及线程池模型

    1.最近项目不是很忙,结合之前看的一些开源代码(skynet及其他github代码)及项目代码,抽空写了一个简单的任务队列当做练习. 2.介绍: 1)全局队列中锁的使用:多线程下,全局队列需要加锁,本 ...

  8. Extjs前端框架解决了什么问题

    Extjs 作为一套企业级富客户端前端开发框架,主要解决了以下问题: 1.DOM Ext.Element: Ext.Element.get()快捷方式Ext.get(),只能以dom的id作为参数去获 ...

  9. init() 方法

    1 /** * servlet init()在web应用程序启动之后,第一个请求到达Servlet之前调用. * 问题1:如果init()中需要处理大量的工作,那么servlet在处理第一个请求需要花 ...

  10. Angular2 中的依赖包详解

    转自:http://blog.csdn.net/feiying008/article/details/53033704 目录 dependencies 和 devDependencies depend ...