從兩個目錄中提取相同的文件

從兩個目錄中提取相同的文件

我正在尋找以下問題的Linux解決方案:

給定兩個包含大量文件的目錄。所有檔案名稱都是隨機的,並且兩個目錄中的檔案名稱都不同。但是,兩個目錄中的某些檔案的內容是相同的。

我想將兩個目錄中出現的所有檔案複製到第三個目錄。 (「同時出現」是指內容相同但名稱相同。)

答案1

假設您的檔案名稱沒有任何空格,且任一目錄中都沒有子目錄,則下列命令會列印具有符合 MD5 和的檔案名稱對:

join -o 1.2,2.2 <(md5sum $D1/* | sort) <(md5sum $D2/* | sort)

若要僅取得其中一個檔案名,請使用-o 1.2-o 2.2

如果檔案名稱(或路徑)可能包含空格,則您需要更加聰明。

如果目錄可能有多個名稱的相同文件,那麼您還需要更加聰明——並且需要準確地決定要做什麼。一種可能性是在進行連接之前過濾掉重複項:

join -o 1.2,2.2 <(md5sum $D1/* | sort | uniq -w16) \
                <(md5sum $D2/* | sort | uniq -w16)

不使用sum

sum輸出16位元校驗和;如果每個目錄中有數百個文件,則在比較 16 位元校驗和時很可能會得到誤報。md5sum也不是絕對安全,但與 128 位元校驗和發生衝突的可能性很小。如有疑問,並且如果確實很重要,cmp您也可以查看這些文件:

join -o 1.2,2.2 <(md5sum $D1/* | sort) <(md5sum $D2/* | sort) |
while read F1 F2; do
  if cmp -s $F1 $F2; then
    cp F1 $D3
  fi
done

(同樣,如果檔案名稱中可能包含空格,則這將無法運作。)

答案2

使用您最喜歡的 shell 來編寫此偽代碼:

cd D1; sum * | while read l; do echo "D1 $l"; done >/tmp/foo
cd D2; sum * | while read l; do echo "D2 $1"; done >>/tmp/foo

sort -n /tmp/foo | awk '
$1 == prev_cs { echo "cp $3 dest"}
     /prev_cs = $1/
' | shell

如果您願意,可以在發布副本之前保存 awk 輸出以供查看

答案3

這可能會完成這項工作,就像 mpez0 的 ans 複製重複項一樣。

find {tst1,tst2} -exec sum {} {} \; 2> /dev/null | sort | uniq

相關內容