• 比较两个UNIX文本文件,找出新增内容(diff和comm命令)(转)


    本文转自 http://blog.xuyuan.me/2011/03/17/unix_diff.html

    最近项目中遇到一个奇怪的bug,仔细检查后发现是由一行简单代码引起的。这行代码要做的事情很简单:比较两个UNIX文本文件,找出并打印文本2比文本1新增加的内容。代码调用了diff命令,示例如下:

    # temp1.txt文件内容
    $> cat temp1.txt
    20110224
    20110225
    20110228
    20110301
    20110302

    # temp2.txt文件内容
    $> cat temp2.txt
    20110228
    20110301
    20110302

    20110303
    20110304

    # diff命令输出结果
    $> diff temp1.txt temp2.txt
    1,2d0
    < 20110224
    < 20110225
    5a4,5
    > 20110303
    > 20110304

    # 只输出temp2.txt文件独有的内容
    $> diff temp1.txt temp2.txt | grep "> " | sed 's/> //g'
    20110303
    20110304

    可以看到,输出结果去掉了两个文件的共同内容,只输出了temp2.txt的新增部分,和预想的结果一样。

     

    但是,随着temp1.txt文件内容的增加,diff命令出现了不同预期的结果:

    $> cat temp1.txt
    20101216
    20101217
    20101220
    20101221
    20101223
    20101224
    20101227
    20101228
    20101229
    20101230
    20101231
    20110103
    20110104
    20110105
    20110106
    20110107
    20110110
    20110111
    20110112
    20110113
    20110114
    20110117
    20110118
    20110119
    20110120
    20110121
    20110124
    20110125
    20110126
    20110127
    20110128
    20110131
    20110201
    20110202
    20110203
    20110204
    20110207
    20110208
    20110209
    20110210
    20110211
    20110214
    20110215
    20110216
    20110217
    20110218
    20110221
    20110222
    20110223
    20110224
    20110225
    20110228
    20110301
    20110302
    20110303

    $> cat temp2.txt
    20110228
    20110301
    20110302
    20110303

    20110304
    20110307
    20110308
    20110309
    20110310
    20110311
    20110314

    $> diff temp1.txt temp2.txt
    1,55c1,11
    < 20101216
    < 20101217
    < 20101220
    < 20101221
    < 20101223
    < 20101224
    < 20101227
    < 20101228
    < 20101229
    < 20101230
    < 20101231
    < 20110103
    < 20110104
    < 20110105
    < 20110106
    < 20110107
    < 20110110
    < 20110111
    < 20110112
    < 20110113
    < 20110114
    < 20110117
    < 20110118
    < 20110119
    < 20110120
    < 20110121
    < 20110124
    < 20110125
    < 20110126
    < 20110127
    < 20110128
    < 20110131
    < 20110201
    < 20110202
    < 20110203
    < 20110204
    < 20110207
    < 20110208
    < 20110209
    < 20110210
    < 20110211
    < 20110214
    < 20110215
    < 20110216
    < 20110217
    < 20110218
    < 20110221
    < 20110222
    < 20110223
    < 20110224
    < 20110225
    < 20110228
    < 20110301
    < 20110302
    < 20110303

    ---
    > 20110228
    > 20110301
    > 20110302
    > 20110303

    > 20110304
    > 20110307
    > 20110308
    > 20110309
    > 20110310
    > 20110311
    > 20110314

    $> diff temp1.txt temp2.txt | grep "> " | sed 's/> //g'
    20110228
    20110301
    20110302
    20110303

    20110304
    20110307
    20110308
    20110309
    20110310
    20110311
    20110314

    可以看到,diff命令不但输出了temp2.txt文件的新增部分(20110304-20110314),也同时输出了两个文件的共同内容(20110228-20110303),从而导致了与预期不一致的结果。

    查看diff命令的man手册发现,diff的作用是比较两个文件的内容,并输出两个文件之间的差异,产生一个能够将两个文件互相转换的列表,但这个列表并不能100%保证是最小集。于是,在上面的例子中,我们看到diff给出了temp1.txt和temp2.txt文件的比较差异结果,但其中包含了两个文件的共同部分,因此与预期不一样。

     

    一个解决的方法是,可以用comm命令代替diff,示例如下:

    $> comm -13 temp1.txt temp2.txt
    20110304
    20110307
    20110308
    20110309
    20110310
    20110311
    20110314

    comm命令用来比较两个文件,具体用法:

    comm [-123] file1 file2
    -1 过滤file1独有的内容
    -2 过滤file2独有的内容
    -3 过滤file1和file2重复的内容

     

    PS,看了下diff的输出格式,主要有以下几种:

    n1 a n3,n4
    n1,n2 d n3
    n1,n2 c n3,n4

    例如"1,2d0" "5a4,5" "1,55c1,11"等。其中n1和n2指第一个文件的行数,n3和n4指第二个文件的行数。"a"代表add增加,"d"代表delete删除,"c"代表change整块变动。

    有了diff的输出结果,可以使用patch命令将一个文件恢复成另一个,例如:

    $> cat temp1.txt
    20110224
    20110225
    20110228
    20110301
    20110302

    $> cat temp2.txt
    20110228
    20110301
    20110302
    20110303
    20110304

    $> diff temp1.txt temp2.txt > temp.diff

    $> cat temp.diff
    1,2d0
    < 20110224
    < 20110225
    5a4,5
    > 20110303
    > 20110304

    # 使用temp.diff和temp1.txt恢复temp2文件
    $> patch -i temp.diff -o temp2_restore.txt temp1.txt
    Looks like a normal diff.
    done

    # 完成后temp2_restore和原temp2文件内容一致
    $> cat temp2_restore.txt
    20110228
    20110301
    20110302
    20110303
    20110304


    博主ma6174对本博客文章(除转载的)享有版权,未经许可不得用于商业用途。转载请注明出处http://www.cnblogs.com/ma6174/

    对文章有啥看法或建议,可以评论或发电子邮件到ma6174@163.com


  • 相关阅读:
    CEO良言:创业就请在29岁前做富翁
    在酒桌上看出她是哪种女人!
    巴菲特的人生财富课
    曹操的领导力:羊群变狮群(领导艺术终极体现)
    商业模式木桶短板原理与长板原理
    这三种力量,让你的人生从此大不一样……
    都市男女的30句妙语叹息
    郎咸平:诸葛亮是一名优秀的企业家吗?
    做小生意,解决生活中的问题:创业路上的成功感悟
    100个成功经验(价格不菲的培训课程笔记摘要)
  • 原文地址:https://www.cnblogs.com/ma6174/p/2348904.html
Copyright © 2020-2023  润新知