
我有兩個目錄A和B;每一個都包含很多子目錄
geom001, geom002 ....etc
每個子目錄都包含一個名為 results.txt 的檔案。我想在不打開其中任何一個的情況下比較A 中的每個文件與B 中的每個文件,並查找A 中是否有一個或多個文件與B 中的一個或多個文件類似。在a 中使用以下命令循環搜尋所有檔案?
cmp --silent file1 file2 || echo "file1 and file2 are different"
答案1
如果文件完全相同,那麼它們的md5sum
s 將完全相同,因此您可以使用:
find A/ B/ -type f -exec md5sum {} + | sort | uniq -w32 -D
md5sum 的長度始終為 128 位元(或 16 個位元組或 32 個十六進位數字),且md5sum
程式輸出使用十六進位數字。因此,我們使用命令-w32
上的選項uniq
來僅比較每行的前 32 個字元。
這將列印全部具有非唯一 md5sum 的檔案。即重複。
注意:這將檢測重複文件,無論它們位於 A/ 或 B/ 中的哪個位置 - 因此如果/A/subdir1/file
和A/subdir2/otherfile
相同,它們仍然會列印。如果有多個重複項,則將全部列印出來。
您可以透過管道將 md5sums 從輸出中刪除,例如,或awk '{print $2}'
與cut
或等sed
。使用加工。awk
perl
答案2
我想這會讓你更接近。它將列出 A 中所有名為 results 的檔案與 B 中名為 results 的所有檔案的 cmp 輸出。
find ./A -name results | xargs -I REPLACESTR find ./B -name results -exec cmp REPLACESTR {} \;
答案3
問題/請求的表面挑戰可能是遞歸方面。
假設這是一個足夠的實用程序,並且要比較的cmp
資料夾/目錄具有相同的結構(即相同的檔案和資料夾)並且駐留在相同的根路徑中 - 您可以嘗試類似的操作:1
2
#!/bin/bash
ROOT=$PWD ; # #// change to absolute path eg: /home/aphorise/my_files
PWD1="1/*" ;
PWD2="2/*" ;
# #// Get lengths of seperators
IFS=/ read -a DP <<< ${ROOT} ;
PLEN1=${#DP[*]} ;
IFS=/ read -a DP <<< ${PWD1} ;
PLEN1=$(echo "${#DP[*]}" + $PLEN1 - 1 | bc) ;
IFS=/ read -a DP <<< ${PWD2} ;
PLEN2=${#DP[*]} ;
# #// Set absolute paths:
PWD1="${ROOT}/${PWD1}" ;
PWD2="${ROOT}/${PWD2}" ;
DIFFS=0 ;
function RECURSE()
{
for A_FILE in $1 ; do
if [ -d $A_FILE ] ; then
RECURSE "$A_FILE/*" ;
else
IFS=/ read -a FP <<< ${A_FILE} ;
B_FILE="${PWD2:0:${#PWD2}-${#PLEN2}}$( IFS=/ ; printf "%s" "${FP[*]:$PLEN1:512}"; )" ;
if ! cmp ${A_FILE} ${B_FILE} 1>/dev/null ; then printf "$A_FILE --> $B_FILE <-- DIFFER.\n" ; ((++DIFFS)) ; fi ;
fi ;
done ;
}
printf "Starting comparison on $PWD1 @ $(date)\n\n" ;
RECURSE "${PWD1[*]}" ;
if ((DIFFS != 0)) ; then printf "\n= $DIFFS <= differences detected.\n" ; fi ;
printf "\nCompleted comparison @ $(date)\n" ;
更新:
接下來是另一個腳本 - 在收到額外回饋之後 - 無條件地將目錄中的所有文件1
與2
:
#!/bin/bash
PWD1="$PWD/1/*" ;
PWD2="$PWD/2/*" ;
DIFFS=0 ;
NODIFFS=0 ;
printf "Starting comparison on $PWD1 @ $(date)\n\n" ;
FILES_A=$(find ${PWD1} -type f) ;
FILES_B=$(find ${PWD2} -type f) ;
for A_FILE in ${FILES_A[*]} ; do
for B_FILE in ${FILES_B[*]} ; do
if ! cmp ${A_FILE} ${B_FILE} 1>/dev/null ; then
printf "$A_FILE & $B_FILE <- DIFFER.\n" ;
((++DIFFS)) ;
else
printf "\n-> SAME: $A_FILE & $B_FILE\n" ;
((++NODIFFS)) ;
fi ;
done ;
done ;
printf "\n= $DIFFS <= differences detected - & - $NODIFFS <= exact matches.\n" ;
printf "\nCompleted comparison @ $(date)\n" ;