我正在嘗試透過一個命令中的 md5sum 來比較兩個資料夾中的所有檔案。有些人喜歡 Debian 中的以下 (bash):
$ cd ~/FOLDER1
$ md5sum ~/FOLDER2/* | md5sum -c -
這個想法是,第一個 md5sum 的雜湊值輸出將傳遞到第二個 md5sum 並用作輸入檔。然而,對此的測試表明,它只是將 FOLDER2 中的每個檔案與其自身進行比較,並為每個檔案傳回「OK」。我認為這不起作用的原因是因為第一個 md5sum 輸出的檔案名稱包含完整路徑。我看過md5deep
但沒有找到任何可以幫助我的東西。我知道可以對一個資料夾執行 md5sum,將結果寫入一個文件,然後使用該文件作為第二個 md5sum 的輸入。我想透過管道在一行中完成所有操作,而不是使用兩個命令並寫出一個檔案。
編輯:接受的答案這裡(使用diff
)可能會做我想要的,但我不知道是否diff
(正確)比較二進位。
編輯:使用 md5sum (顯示檔案名稱和「確定」)取得我想要的輸出,我必須編寫一個批次檔。執行與diffFolders.sh ~/FOLDER1 ~/FOLDER2
.
#!/bin/bash
HERE=$PWD
cd "$1"
md5sum * > /tmp/md5sum.cmp
cd "$2"
md5sum -c /tmp/md5sum.cmp
cd $HERE
該腳本只會比較~/FOLDER
.如果~/FOLDER2
有其他文件,則不會對這些文件進行比較,並且沒有輸出表明它們甚至存在。
答案1
您可以使用流程替代將 2 個 md5sum 的輸出傳遞給 diff。在這種情況下,Diff 就可以了,因為 md5 輸出是純文字。就像是:
diff <(md5 ~/FOLDER1/* | awk '{print $4}') <(md5 ~/FOLDER2/* | awk '{print $4}')
抱歉,我這裡沒有 Debian,無法對其進行測試。以上是在具有 md5 的 OS X 上測試的,輸出可能略有不同。在 OS X 上,md5 的第 4 列是實際的 md5 總和,這就是我只採用這些列的原因。
除了 awk 之外,您還可以使用cut
,但您可能需要更改分隔符號才能取得第四列(這些不是製表符分隔的)。
答案2
來自我的 .bashrc 檔案。
很舊的東西,應該可以寫很多排序器程式碼。我一直沒有時間重寫它。 (就像其他所有用於臨時修復、永久使用的東西一樣)我發布了這段可恥的程式碼,希望有人可以做得更好並發布結果:-)
特徵 :
- 遞歸方向橫向
- md5sum 檢查唯一性/差異
- 以完整路徑列出更新的文件
程式碼說明了一切。 arg1 是舊目錄,arg2 是新目錄。
function find-updated-files-between-old-new(){
[ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( ( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n")
)|sort -k1.2|tee 1>/dev/null >(uniq -us1|awk -v B="$2" 'BEGIN{sub("/$",""B)}/^-/{print B substr($0,3);
}') >(uniq -ds1|awk -vA="$1" -vB="$2" 'BEGIN{B=g(B);A=g(A)}{
C=substr($0,3);if(f(A)!=f(B))print B C;}function g(y){sub("/$","",y);return y}
function f(y,z,e){e="md5sum \""y""C"\"";e|getline z;close(e);return substr(z,1,32)}' )
) | cat
}
如函數名稱所示
function find-files-name-collision-between-dir1dir2(){
[ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n") )|sort -k 1.2 | uniq -d -s 1
}
只是為了完整性
function mv-mergedir1todir2(){
[ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." && return 1;
( cd "$1" ; tar cf - . ) | (cd "$2" ; tar --keep-old-files xvf - )
echo -e "Done. Duplicate filnames are not replaced. \n#Use \n# ( cd \"$1\" ; tar cf - . ) | (cd \"$2\" ; tar --overwrite xvf - ) \n#if you do not like that. "
}
這段糟糕的程式碼應該會從我的 bashrc 中刪除,但它已經存在很久了...
答案3
有點長,但返回檔名,如果匹配就OK。它不使用“-c”,而只是比較對每個資料夾中的檔案執行 md5sum 的兩個字串輸出。
for f in *; do [[ -f $f ]] && if [ $(md5sum "$f" | cut -d" " -f1) == $(md5sum dir2/"$f" | cut -d" " -f1) ]; then echo "$f" "OK"; else echo "$f" "MODIFIED"; fi; done