隨筆-314  評論-209  文章-0  trackbacks-0

          在項目中遇到一個奇怪的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重復的內容
           
          備注:
          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
          posted on 2016-03-24 12:09 xzc 閱讀(1074) 評論(1)  編輯  收藏 所屬分類: linux/unix

          評論:
          # re: linux diff與comm命令比較文件(找出新增內容) 2016-03-24 12:09 | xzc
          comm -23 ${logs_path}/${shell_name}_${file_name_prefix}_ftp.log ${logs_path}/${shell_name}_${file_name_prefix}_hdfs.log  回復  更多評論
            
          主站蜘蛛池模板: 北辰区| 辽宁省| 长宁区| 北京市| 沅陵县| 商河县| 互助| 吉安县| 获嘉县| 敦煌市| 乐平市| 凤山县| 斗六市| 湛江市| 百色市| 德化县| 桐柏县| 开封市| 潜山县| 莱州市| 卓资县| 芮城县| 旬阳县| 名山县| 治县。| 九江市| 乌什县| 商水县| 孙吴县| 逊克县| 东方市| 温州市| 牟定县| 会昌县| 江口县| 平山县| 古丈县| 广南县| 麻栗坡县| 玉田县| 松阳县|