shell指令碼樣本:批量比較多個檔案的內容是否相同,

來源:互聯網
上載者:User

shell指令碼樣本:批量比較多個檔案的內容是否相同,

要比較兩個檔案的內容是否完全一致,可以簡單地使用diff命令。例如:

diff file1 file2 &>/dev/null;echo $?

但是diff命令只能給定兩個檔案參數,因此無法一次性比較多個檔案(目錄也被當作檔案),而且diff比較非文本類檔案或者極大的檔案時效率極低。

這時可以使用md5sum來實現,相比diff的逐行比較,md5sum的速度快的多的多。

md5sum的使用方法見:Linux中檔案MD5校正。

但md5sum只能通過查看md5值來間接比較檔案是否相同,要實現批量自動比較,則需要寫成迴圈。指令碼如下:

#!/bin/bash############################################################  description: compare many files one time               ##  author     : 駿馬金龍                                   ##  blog       : http://www.cnblogs.com/f-ck-need-u/       ############################################################# filename: md5.sh# Usage: $0 file1 file2 file3 ...IFS=$'\n'declare -A md5_array# If use while read loop, the array in while statement will# auto set to null after the loop, so i use for statement# instead the while, and so, i modify the variable IFS to# $'\n'.# md5sum format: MD5  /path/to/file# such as:80748c3a55b726226ad51a4bafa1c4aa /etc/fstabfor line in `md5sum "$@"`do    index=${line%% *}    file=${line##* }    md5_array[$index]="$file ${md5_array[$index]}"done# Traverse the md5_arrayfor i in ${!md5_array[@]}do    echo -e "the same file with md5: $i\n--------------\n`echo ${md5_array[$i]}|tr ' ' '\n'`\n"done 

為了測試該指令碼,先複製幾個檔案,並修改其中幾個檔案的內容,例如:

[root@xuexi ~]# for i in `seq -s' ' 6`;do cp -a /etc/fstab /tmp/fs$i;done[root@xuexi ~]# echo ha >>/tmp/fs4[root@xuexi ~]# echo haha >>/tmp/fs5

現在,/tmp目錄下有6個檔案fs1、fs2、fs3、fs4、fs5和fs6,其中fs4和fs5被修改,剩餘4個檔案內容完全相同。

[root@xuexi tmp]# ./md5.sh /tmp/fs[1-6]the same file with md5: a612cd5d162e4620b442b0ff3474bf98--------------------------/tmp/fs6/tmp/fs3/tmp/fs2/tmp/fs1the same file with md5: 80748c3a55b726226ad51a4bafa1c4aa--------------------------/tmp/fs4the same file with md5: 30dd43dba10521c1e94267bbd117877b--------------------------/tmp/fs5

更具通用性地比較方法:比較多個目錄下的同名檔案。

[root@xuexi tmp]# find /tmp -type f -name "fs[0-9]" -print0 | xargs -0 ./md5.sh  the same file with md5:a612cd5d162e4620b442b0ff3474bf98--------------------------/tmp/fs6/tmp/fs3/tmp/fs2/tmp/fs1the same file with md5:80748c3a55b726226ad51a4bafa1c4aa--------------------------/tmp/fs4the same file with md5:30dd43dba10521c1e94267bbd117877b--------------------------/tmp/fs5

指令碼說明:

(1).md5sum計算的結果格式為"MD5 /path/to/file",因此要在結果中既輸出MD5值,又輸出相同MD5對應的檔案,考慮使用數組。

(2).一開始的時候我使用while迴圈,從標準輸入中讀取每個檔案md5sum的結果。語句如下:

md5sum "$@" | while read index file;do    md5_array[$index]="$file ${md5_array[$index]}"done

但由於管道使得while語句在子shell中執行,於是while中賦值的數組md5_array在迴圈結束時將失效。所以可改寫為:

while read index file;do    md5_array[$index]="$file ${md5_array[$index]}"done <<<"$(md5sum "$@")"

不過我最終還是使用了更繁瑣的for迴圈:

IFS=$'\n'for line in `md5sum "$@"`do    index=${line%% *}    file=${line##* }    md5_array[$index]="$file ${md5_array[$index]}"done

但md5sum的每行結果中有兩列,而for迴圈採用預設的IFS會將這兩列分割為兩個值,因此還修改了IFS變數的值為$'\n',使得一行賦值一次變數。

(3).index和file變數是為了將md5sum的每一行結果拆分成兩個變數,MD5部分作為數組的index,file作為陣列變數值的一部分。因此,數組指派陳述式為:

md5_array[$index]="$file ${md5_array[$index]}"

(4).數組賦值完成後,開始遍曆數組。遍曆的方法有多種。我採用的是遍曆數組的index列表,即每行的MD5值。

# Traverse the md5_arrayfor i in ${!md5_array[@]}do    echo -e "the same file with md5: $i\n--------------\n`echo ${md5_array[$i]}|tr ' ' '\n'`\n"done  

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7430259.html註:若您覺得這篇文章還不錯請點擊下右下角的推薦,有了您的支援才能激發作者更大的寫作熱情,非常感謝!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.