如何在不開啟文件的情況下比較不同的文件?

如何在不開啟文件的情況下比較不同的文件?

我有兩個目錄A和B;每一個都包含很多子目錄

geom001, geom002 ....etc

每個子目錄都包含一個名為 results.txt 的檔案。我想在不打開其中任何一個的情況下比較A 中的每個文件與B 中的每個文件,並查找A 中是否有一個或多個文件與B 中的一個或多個文件類似。在a 中使用以下命令循環搜尋所有檔案?

cmp --silent  file1 file2  || echo "file1 and file2 are different"

答案1

如果文件完全相同,那麼它們的md5sums 將完全相同,因此您可以使用:

find A/ B/ -type f -exec md5sum {} + | sort | uniq -w32 -D

md5sum 的長度始終為 128 位元(或 16 個位元組或 32 個十六進位數字),且md5sum程式輸出使用十六進位數字。因此,我們使用命令-w32上的選項uniq來僅比較每行的前 32 個字元。

這將列印全部具有非唯一 md5sum 的檔案。即重複。

注意:這將檢測重複文件,無論它們位於 A/ 或 B/ 中的哪個位置 - 因此如果/A/subdir1/fileA/subdir2/otherfile相同,它們仍然會列印。如果有多個重複項,則將全部列印出來。

您可以透過管道將 md5sums 從輸出中刪除,例如,或awk '{print $2}'cut或等sed。使用加工。awkperl

答案2

我想這會讓你更接近。它將列出 A 中所有名為 results 的檔案與 B 中名為 results 的所有檔案的 cmp 輸出。

find ./A -name results | xargs -I REPLACESTR find ./B -name results -exec cmp REPLACESTR {} \;

答案3

問題/請求的表面挑戰可能是遞歸方面。

假設這是一個足夠的實用程序,並且要比較的cmp資料夾/目錄具有相同的結構(即相同的檔案和資料夾)並且駐留在相同的根路徑中 - 您可以嘗試類似的操作:12

#!/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" ;

更新:

接下來是另一個腳本 - 在收到額外回饋之後 - 無條件地將目錄中的所有文件12

#!/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" ;

相關內容