
dir1
我需要找到所有存在於 中但不存在於 中的文件dir2
。dir1
並且dir2
可能有不同的結構,所以diff -r
不能很好地工作。
答案1
嘗試建立一個不帶路徑的文件列表。這樣,您就可以比較兩個目錄。但是,檔案名稱應該全部不同。如果在 dir1 的不同子目錄中重複使用相同的檔案名,則刪除路徑將刪除檔案名稱的唯一性。您可以獲得不帶路徑名的每個目錄的列表,如下所示:
find dir1/ -exec basename {} \; | sort
find dir2/ -exec basename {} \; | sort
全部加起來看起來像這樣
diff <(find dir1/ -exec basename {} \; | sort) <(find dir2/ -exec basename {} \; | sort)
我看到有評論建議使用 fdupes。fdupes
如果絕對有更好的解決方案。
答案2
一個粗略的方法可能是使用md5sum
.請注意,長度為零的檔案始終會被視為重複項,因此您可能find
只需要長度至少為 1 個位元組的檔案。
find /first/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path1.txt
cut -b1-32 < /tmp/md5-path1-short.txt
find /second/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path2.txt
cut -b1-32 < /tmp/md5-path2-short.txt
path1 中不在 path2 的檔案(刪除「-v」選項
grep /tmp/md5-path1.txt -v -F -f /tmp/md5/path2-short.txt
CYA等級:專業
上面的 32 是因為 MD5 雜湊值的長度是 32 個位元組。例如,如果您使用 ,sha1sum
它的碰撞機會更小,那麼您將使用長度 40;sha224sum
需要 56、sha256sum
需要 64 和sha512sum
128。
CYA等級:偏執
這在某些元資料保存在檔案中的快取方案中可能不起作用其名稱包含原始檔案的哈希值。
(這實際上發生在我幾年前安裝的 Wordpress + Magento 上,我們想要遷移巨大的文章緩存,同時刪除過時的條目)。
在這種情況下,您必須使用不同的雜湊方案 - 快速修復 - 以避免grep
傳回誤報,將元資料條目誤認為原始檔案(因此,如果快取使用 MD5,則使用 SHA1,反之亦然);或使用sed
重寫“短”文件中的所有行以在開頭添加“^”,從而使其成為錨定的正則表達式,並刪除標誌-F
以grep
將文件作為正則表達式而不是純字串處理。
答案3
所以,我找到的部分解決方案是:
find dir1 -type f | grep -vxFf <(fdupes -r dir1 dir2)
但我說“部分”,因為如果 中有重複項dir1
,它們將不會顯示,因此您需要fdupes -r dir1
先運行。