相关文章推荐
近视的春卷  ·  tcpclient ...·  1 年前    · 
礼貌的米饭  ·  C/C++ 恨透了 double free ...·  1 年前    · 

最近有几个实时流项目需要基于新框架改造,改造完成之后要测试对比数据是否正确,网上找了一下关于基于shell命令进行文本文件对比的信息。以下就是一篇很不错的文章,转载过来以后还能用到:

转载地址:http://blog.csdn.net/tianmohust/article/details/6997924

1  comm命令

在我们的开发和运营中,特别是对业务进行监控的时候,我们常常需要写一些监控shell脚本,而这些脚本需要求两个文件的共同的记录列表或者只出现在第一个文件但不出现在第二个文件的记录列表的场景,此时,comm命令则是您解决此类问题的利器和助手。

随意man comm下,可以在linux下看到该命令的使用方法:

NAME
comm - compare two sorted files line by line

SYNOPSIS
comm [OPTION]... FILE1 FILE2

DESCRIPTION
Compare sorted files FILE1 and FILE2 line by line.

With  no  options,  produce  three-column  output.   Column one contains lines unique to FILE1, column two contains lines
unique to FILE2, and column three contains lines common to both files.

-1     suppress lines unique to FILE1

-2     suppress lines unique to FILE2

-3     suppress lines that appear in both files

--help display this help and exit

--version
output version information and exit

上面是英文说明,下面简单的说明如下:

一,利用comm命令进行处理的文件必须首先通过sort命令进行排序处理并且是unix格式而非dos格式的文本文件;

二,中文说明如下:

功能说明:比较两个已排过序的文件。(使用sort排序)
语  法: comm [-123][--help][--version][第1个文件][第2个文件]
补充说明:这项指令会一列列地比较两个已排序文件的差异,并将其结果显示出来,如果没有指定任何参数,则会把结果分成3栏显示:第1栏仅是在第1个文件中出现过的记录,第2栏是仅在第2个文件中出现过的记录,第3栏则是在第1与第2个文件里都出现过的记录。若给予的文件名改为"-",则 comm 指令会从标准输入设备读取数据。
参  数:
-1   不显示只在第1个文件里出现过的列。
-2   不显示只在第2个文件里出现过的列。
-3   不显示只在第1和第2个文件里出现过的列。
--help   在线帮助。
--version   显示版本信息。
例子
comm - 12     就只显示在两个文件中都存在的行;
comm - 23    只显示在第一个文件中出现而未在第二个文件中出现的行;
comm - 123  则什么也不显示。

例如:找出a.txt文件有而b.txt文件中没有的放在c.txt文件中 (注意:一定要是先排序,即sort)

  1. #!/bin/sh
  2. # author by tianmo
  3. # date 2011-11-21 20:33
  4. #BEGIN
  5. cat a.txt | sort | uniq | sort > a_u.txt
  6. cat b.txt | sort | uniq | sort > b_u.txt
  7. comm -23  a_u.txt  b_u.txt > c.txt
  8. # END
2 diff命令

功能说明:比较文件的差异。

语  法:diff [-abBcdefHilnNpPqrstTuvwy][-<行数>][-C <行数>][-D <巨集名称>][-I <字符或字符串>][-S <文件>][-W <宽度>][-x <文件或目录>][-X <文件>][--help][--left-column][--suppress-common-line][文件或目录1][文件或目录2]

补充说明:diff以逐行的方式,比较文本文件的异同处。所是指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子目录。

参  数:

-<行数>  指定要显示多少行的文本。此参数必须与-c或-u参数一并使用。

-a或--text  diff预设只会逐行比较文本文件。

-b或--ignore-space-change  不检查空格字符的不同。

-B或--ignore-blank-lines  不检查空白行。

-c  显示全部内文,并标出不同之处。

-C<行数>或--context<行数>  与执行"-c-<行数>"指令相同。

-d或--minimal  使用不同的演算法,以较小的单位来做比较。

-D<巨集名称>或ifdef<巨集名称>  此参数的输出格式可用于前置处理器巨集。

-e或--ed  此参数的输出格式可用于ed的script文件。

-f或-forward-ed  输出的格式类似ed的script文件,但按照原来文件的顺序来显示不同处。

-H或--speed-large-files  比较大文件时,可加快速度。

-l<字符或字符串>或--ignore-matching-lines<字符或字符串>  若两个文件在某几行有所不同,而这几行同时都包含了选项中指定的字符或字符串,则不显示这两个文件的差异。

-i或--ignore-case  不检查大小写的不同。

-l或--paginate  将结果交由pr程序来分页。

-n或--rcs  将比较结果以RCS的格式来显示。

-N或--new-file  在比较目录时,若文件A仅出现在某个目录中,预设会显示:

Only in目录:文件A若使用-N参数,则diff会将文件A与一个空白的文件比较。

-p  若比较的文件为C语言的程序码文件时,显示差异所在的函数名称。

-P或--unidirectional-new-file  与-N类似,但只有当第二个目录包含了一个第一个目录所没有的文件时,才会将这个文件与空白的文件做比较。

-q或--brief  仅显示有无差异,不显示详细的信息。

-r或--recursive  比较子目录中的文件。

-s或--report-identical-files  若没有发现任何差异,仍然显示信息。

-S<文件>或--starting-file<文件>  在比较目录时,从指定的文件开始比较。

-t或--expand-tabs  在输出时,将tab字符展开。

-T或--initial-tab  在每行前面加上tab字符以便对齐。

-u,-U<列数>或--unified=<列数>  以合并的方式来显示文件内容的不同。

-v或--version  显示版本信息。

-w或--ignore-all-space  忽略全部的空格字符。

-W<宽度>或--width<宽度>  在使用-y参数时,指定栏宽。

-x<文件名或目录>或--exclude<文件名或目录>  不比较选项中所指定的文件或目录。

-X<文件>或--exclude-from<文件>  您可以将文件或目录类型存成文本文件,然后在=<文件>中指定此文本文件。

-y或--side-by-side  以并列的方式显示文件的异同之处。

--help  显示帮助。

--left-column  在使用-y参数时,若两个文件某一行内容相同,则仅在左侧的栏位显示该行内容。

--suppress-common-lines  在使用-y参数时,仅显示不同之处。

例如: 找出a.txt文件有而b.txt文件中没有的放在c.txt文件中

  1. #!/bin/sh
  2. # author by tianmo
  3. # date 2011-11-21 20:33
  4. #BEGIN
  5. cat a.txt | sort | uniq | sort > a_u.txt
  6. cat b.txt | sort | uniq | sort > b_u.txt
  7. diff   a_u.txt  b_u.txt | grep /<  | awk ' $1 = " " ' > c.txt
  8. # END

3  Linux系统下比较两个文件并删除相同部分

comm -23 file1 file2

grep -v -f file1 file2

/*注::此法在对比数字时候比较凑效果,文本对比不建议使用*/

awk '{print NR,$0}' file1 file2 |sort -k2|uniq -u -f 1|sort -k1|awk '{print $2}'

awk '{print $0}' file1 file2 |sort|uniq -u

4 Linux Shell删除两个文件相同部分

因为在面试中遇到一个这样的问题,当时模模糊糊的,没有很确定的回答出来,后来上网查了一下结果,这里总结一下。首先描述一下这个问题:比如两个文件file1和file2,删除两个文件中共同的部分,留下两个文件中独自有的部分。在网上找到一篇解决的答案,地址在这里 http://hi.baidu.com/robertoyuan/blog/item/559483c4946ed5a78226acac.html 。这里提到三种方法,但是没有给具体的解释。

方法一:使用grep grep -v -f file1 file2 &&  grep -v -f file2 file1

grep命令的详细使用方法,可以参考man,这里有一个简单实用的介绍: http://linux.ccidnet.com/art/3067/20070313/1035613_1.html 。在方法一中,用到了两个参数。参数-v,表示invert match,即反向匹配,输出没有匹配上的项。参数-f,表示从文件中读取匹配模板(pattern)。方法一中的前一部分,在文件file1中匹配模板,来反向匹配文件file2中的内容,即输出文件file2中,在file1中没有的内容。后面的一部分同理可得,输出文件file1中,在file2中没有的内容。

方法二:实用comm comm -3 file1 file2

这个方法看起来最简单。命令comm的功能就是,逐行比较两个排好序的文件,默认输出有三列:只在file1中有的行、只在file2中有的行、在file1和file2中共有的行。有参数-1 -2 -3,分别来抑制输出对应的列。例如在我们的方法二中,实用-3参数,不输出file1和file2中共有的部分。即能达到我们本文的目的。
但是注意到,comm比较排好序的两个文件,comm在处理文件的时候,首先要查看文件是否有序,例如file1和file2的内容如下:

line0
line2

line2

从这个结果中我们可以看到,这还是不是我们真正想要的结果。这里可体现comm的另一个特征,就是逐行比较。它是对file1和file2进行逐行往下的比较,检测是否相同。所以,在用comm的时候,要根据具体的情况进行分析了。

方法三:使用awk
  1. awk '{print NR, $0}' file1 file2 | sort -k2 | uniq -u -f 1 | sort -k1 | awk '{print $2}'

awk命令的使用,听牛人说可谓博大精深,我也没有太搞清楚。这里只是使用了一些简单的功能。下面以我自己的理解来解释一下上面的shell代码。awk就是文本的解释器和过滤器。awk把每一行看成是一个记录(record),每个记录使用分隔符(默认是空格)把每条记录分成若干域。awk内置参数$0表示整行,$1、$2...分别表示各域,内置参数NR,表示记录的计数,awk '{print NR, $0}' file1 file2表示依次读取file1 file2,打印出每行,并且在前面添加行号。

命令sort,就是对行进行排序,参数-k表示根据各行的第几个参数关键字开进行排序,这里的-k2表示根据第二个关键字开始进行排序。

命令uniq,进行报告或者忽略重复的行,参数-u,表示只是打印出唯一的行(unique lines),-f表示忽略的每行的前n个域的比较。

grep -xf file1 file2

补充的重要内容:

1、统计两个文本文件的相同行

grep -Ff file1 file2

2、统计file2中有,file1中没有的行

grep -vFf file2 file1

如何比较两个文件并去删除相同的内容

for i in $(<file1); do grep $i file2 || echo $i >>tmp1 ; done

输出相同行:

$grep -wf file1 file2

输出不同行

$grep -wvf file1 file2

最近有几个实时流项目需要基于新框架改造,改造完成之后要测试对比数据是否正确,网上找了一下关于基于shell命令进行文本文件对比的信息。以下就是一篇很不错的文章,转载过来以后还能用到:转载地址:http://blog.csdn.net/tianmohust/article/details/6997924 1  comm命令在我们的开发和运营中,特别是对业务进行监控的时候,我们
里提示一下:ubuntu的翻译很多都是字面直译,存在很多问题,所以建议大家参照我这里的解释。当然本来也是有些赶文的嫌疑,望指正。 经常在linux上操作,有在不同的目录下切换某几个固定的 命令 ,或者修改几个固定的 文件 ,这时候,如果能在一个目录下就操作他们,会是一件多么轻松的事情。我们来看看链接 命令 ln ln 全称是link 顾名思义,这是一个建立一个链接。怎么去理解呢?它的功能类似于Mac OS的别名或者Windows的快捷方式, 删除不会影响 文件 本身。 说明:(直接看看斜体,就行了) 链接可分为两种:硬链接(hard link)与软链接(symbolic link), 不论是那种类型的链
自从法现 SSH 可以执行远端 命令 后,ftp 软件也渐渐很少用了。 每次更新服务器代码,都要打包、上传、登录到服务器修改 文件 权限、更新 Cache 等等,又慢又容易出错,所以做成脚本,一次帮我搞定,自己就点上一根烟坐在电脑面前发呆,要么就玩会儿《植物大战僵尸》啥的,悠闲! PS: Ant 以及 Phing 用户,你们可以无视了… 我只是喜欢玩 Shell 而已。 代码如下: #!/bin/sh HOME=’/cygdrive/d/public_html/myproject’ ## 先打包本地代码 ## 排除如下 文件 : *.svn, *.bat, upload.sh, cache
1 com m 命令 在我们的开发和运营中,特别是对业务进行监控的时候,我们常常需要写一些监控 shell 脚本,而这些脚本需要求 两个 文件 共同 的记录列表或者只出现在第一个 文件 但不出现在第二个 文件 的记录列表的场景,此时, com m 命令 则是您解决此类问题的利器和助手。      随意man com m下,可以在linux下看到该 命令 的使用方法: com m - com pare
输出 两个 文件 中相同的行 grep -f $file1.txt $file2.txt root@ae02635267dc:/workspace/autohome/test/ shell /awk# cat file2.txt |shuf|head -n 2 >file2_part.txt root@ae02635267dc:/workspace/autohome/test/ shell /awk# cat file2.txt name1 data1 dada2 data3 data4 dad.
在Linux系统中,想要将 两个 文件 拼接在一起,可以使用 shell 指令 cat。cat指令用于显示 文件 内容,同时还可以将多个 文件 的内容进行连接。 使用 cat 指令,可以将 两个 文件 拼接在一起,具体操作步骤如下: 1. 打开终端(Terminal)。 2. 进入存放需要拼接的 两个 文件 文件 目录。 3. 运行 cat 指令,执行以下 命令 : $ cat file1 file2 > file_new 其中 file1 和 file2 分别表示需要拼接的 两个 文件 ,file_new 表示新生成的 文件 名。 4. 运行上述 命令 后, 两个 文件 的内容就会拼接在一起,保存在 file_new 文件 中。 以上就是使用 cat 指令将 两个 文件 拼接在一起的详细步骤。但是需要注意的是, 两个 文件 需要属于同一类型或者格式,不然拼接后的 文件 可能会出现乱码或者格式错误的情况。