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. 对linux内核创建flash上的各分区源码进行分析

    1.注意:内核源码版本为4.9 2.首先注意关键字符串"partitions found on MTD device 这句话在drivers/mtd/mtdpart.c的parse_mtd_ ...

  2. Byte[]分配在哪里?

    http://stackoverflow.com/questions/1113819/arrays-heap-and-stack-and-value-types Your array is alloc ...

  3. Mybatis中使用自定义的类型处理器处理枚举enum类型

    知识点:在使用Mybatis的框架中,使用自定义的类型处理器处理枚举enum类型 应用:利用枚举类,处理字段有限,可以用状态码,代替的字段,本实例,给员工状态字段设置了一个枚举类 状态码,直接赋值给对 ...

  4. 同余定理简单应用 - poj2769 - hdu 1021 - hdu 2035

    同余问题 基本定理: 若a,b,c,d是整数,m是正整数, a = b(mod m), c = d(mod m) a+c = b+c(mod m) ac = bc(mod m) ax+cy = bx+ ...

  5. CentOs64位编译安装hadoop-2.6.0

    官方提供的hadoop-2.x版本貌似都是32位的,在64位机子下使用可能会报错,最好使用官方提供的源码进行本地编译,编译成适合本地硬件环境的64位软件包. Hadoop是使用Java语言开发的,但是 ...

  6. WinCE数据通讯之Web Service篇

    准备写个WinCE平台与数据库服务器数据通讯交互方面的专题文章,今天先整理个Web Service通讯方式. 公司目前的硬件产品平台是WinCE5.0,数据通讯是连接服务器与终端的桥梁,关系着终端的数 ...

  7. hdu 5696 区间的价值 单调栈+rmq

    区间的价值 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem D ...

  8. mac 下如何建立vue-cli项目

    command+space : terminal //检测是否存在node node -v //检测是否带有npm安装管理工具 npm -v //具备进行下一步 //在documnets下建立vue文 ...

  9. shell 数组【了解一下】

    数组编程 #!/bin/bash # array soft=( php mysql nginx ) # 输出第一个 echo ${soft[0]} # 输出所有 echo "This sof ...

  10. Memory Manager surface area changes in SQL Server 2012

    here were various changes to memory related DMVs, DBCC memory status, and Perfmon counters in SQL Se ...