linux比较文件内容命令

时间:2022-11-22 16:29:18

0. 综述: 目前据我所了解的有如下几种方法,来比较两个文件的行,以输出他们的不同之处:

1)   comm mission:    comm [-123] file1 file2 [> sfile]

2)   diff mission:         diff [-opt] file1 file2

3)   grep mission:       grep -v -f file1 file2

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

4)   awk mission:

        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

5) join mission:  join [-i][-a<1或2>][-e<字符串>][-o<格式>][-t<字符>][-v<1或2>][-1<栏位>][-2<栏位>]

1. comm 命令详解

        comm [-123] file1 file2 [> sfile]
        NOTE: file1,file2 must be firstly sorted !
        -1/2/3 means: -1 ----- rid the only retained contents in file1
                      -2 ----- rid the only retained contents in file2
                      -3 ----- rid the communal lines in both two files
         正如,上面说的那样,comm命令运用的前提是针对两个sorted文件!

       该命令是对两个已经排好序的文件进行比较。其中file1和file2是已排序的文件。comm读取这两个文件,然后生成三列输出:仅在file1中出现 的行;仅在file2中出现的行;在两个文件中都存在的行。如果文件名用“- ”,则表示从标准输入读取。

  选项1、2或3抑制相应的列显示。例如comm - 12就只显示在两个文件中都存在的行;comm - 23只显示在第一个文件中出现而未在第二个文件中出现的行;comm - 123则什么也不显示。

2. diff 命令详解  (http://www.phpzixue.cn/detail976.shtml)
diff命令比较两个文木文件,并找出它们的不同。它比comm命令完成更复杂的检查,并且不要求两个文件预先排好序。
    (1)一般格式:     diff[选项]filel  file2
    (2)说明:该命令逐行比较两个文件,列出它们的不同之处,并且告诉用户,为了使两个文件一致,需要修改它们的哪些行。如果两个文件完全一样,则该命令不显示任何输出。
    该命令输出的一般形式如下:
    nl  a  n3, n4(表示把文件I的nl行附加到文件2的n3-n4行后,则二者相同)
    nl, n2  d  n3(表示删除文件1的nl -n2行及文件2的n3行,则二者相同)
    nl, n2  c  n3, n4(表示把文件1的n l -n2行改为文件2的n3,-n4行,则二者相同)
    这些行类似ed命令把文件file l转换成文件file2。字母(a, d和c)之前的行号(nl,n2)是针对文件filel的,其后面的行号(n3, n4)是针对文件file2的。字母a表示附加,字母d表示删除,字母c表示修改。
    在上述形式的每一行的后面跟随受到影响的若干行,以“<”打头的行属于文件file 1,以“>”打头的行属于文件file2o
    diff命令能区分块特别文件、字符特别文件及FIFO(管道文件),不会把它们与普通文件进行比较。   

   (3)选项:   

    -b忽略空格造成的差别。例如,"How   are you”与“How are you”被看做是相同的字符串。
    -c输出格式是带上下文的三行格式。
    -C n输出格式是有上下文的n行格式。
    -e输出一个合法的ed脚本。
    -i忽略字母大小写的区别。
    -r当文件file l和文件file2都是目录时,递归比较找到的各子目录。
    (4)注意:  如果用“一”表示文件filel或文件file2,则意味着标准输入。如果filel或file2是目录,那么diff将使用该目录中的同名文件进行比较。如果filel和filet都是目录,则diff会产生很多信息。如果一个目录中只有一个文件,则产生一条信息,指出该目录路径名和其中的文件名。

   (5)彩色输出不同:ColorDiff

    colordiff file1 file2

   你也可以将 ColorDiff 用于 diff 命令的管道输出:diff -u file1 file2 | colordiff

3. grep 命令详解
http://www.9usb.net/200902/linux-grep.html
http://blog.51yip.com/linux/1008.html
http://blog.csdn.net/tenfyguo/article/details/6387786
http://www.cuug.com/xueyuanzhuanqu/jishuwenzhang/201111/jishuwenzhang-1168.html


4. awk 命令详解
http://www.uplook.cn/index-Index-show-view22152.html

5. join 命令详解
功能说明:将两个文件中,指定栏位内容相同的行连接起来。
语  法: join [-i] [-a<1或2>][-e<字符串>][-o<格式>][-t<字符>][-v<1或 2>][-1<栏位>][-2<栏位>][--help][--version][文件1][文件2]
补充说明:找出两个文件中,指定栏位内容相同的行,并加以合并,再输出到标准输出设备。
参  数:
  -a<1或2>   除了显示原来的输出内容之外,还显示指令文件中没有相同栏位的行。
  -e<字符串>   若[文件1]与[文件2]中找不到指定的栏位,则在输出中填入选项中的字符串。
  -i或--igore-case   比较栏位内容时,忽略大小写的差异。
  -o<格式>   按照指定的格式来显示结果。
  -t<字符>   使用栏位的分隔字符。
  -v<1或2>   跟-a相同,但是只显示文件中没有相同栏位的行。
  -1<栏位>   连接[文件1]指定的栏位。
  -2<栏位>   连接[文件2]指定的栏位。
  --help   显示帮助。
  --version   显示版本信息。
links:
http://unix-cd.com/unixcd12/article_5023.html
http://www.xiaoxiaozi.com/2009/11/17/1642/
http://codingstandards.iteye.com/blog/796299

自己写的一个例子
#!/bin/sh
#2012-06-14
#List format is
#C4 189751 27251 1
#C1 189751 66396 1
#C1 189751 89702 1

time=`date +%y%m%d%H%M%S`
echo "start at 20"$time

fHead=ee
fTail=.txt
file1=$fHead$fTail
file2="sf-"$fHead$fTail
fDiff=$fHead"Diff"$fTail
rm $fDiff

sed -i 's/ /_/g' $file1
sed -i 's/ /_/g' $file2
time=`date +%y%m%d%H%M%S`
echo "step 1: done the sed s/ /_/g on 20"$time

awk '{print $0}' $file1 $file2 |sort|uniq -u > $fDiff
time=`date +%y%m%d%H%M%S`
echo "step 2: done the awk diff on 20"$time

fTemp=$fHead"TempDiff"$fTail
fNew=$fHead"DetailDiff"$fTail
rm $fTemp $fNew
cp $fDiff $fTemp

for i in `cat $fTemp`
do

  line=""
  line=`cat $file1 | grep $i`
  #echo "1: line is " $line
  if [ "$line" != "" ]
  then
    echo "only mine have:" $line >> $fNew
    sed -i '/'$i'/d' $fTemp
  fi

  line=""
  line=`cat $file2 | grep $i`
  #echo "2: line is " $line
  if [ "$line" != "" ]
  then
    echo "only Bham have:" $line >> $fNew
    sed -i '/'$i'/d' $fTemp
  fi

done
time=`date +%y%m%d%H%M%S`
echo "step 3: Done on 20"$time