다른 파일을 열지 않고 어떻게 비교할 수 있나요?

다른 파일을 열지 않고 어떻게 비교할 수 있나요?

두 개의 디렉토리 A와 B가 있습니다. 각각에는 많은 하위 디렉터리가 포함되어 있습니다.

geom001, geom002 ....etc

각 하위 디렉터리에는 results라는 파일이 포함되어 있습니다. A의 각 파일을 열지 않고 B의 각 파일과 비교하고 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개의 16진수)이며 md5sum프로그램 출력에서는 16진수를 사용합니다. 따라서 명령 -w32의 옵션을 사용하여 uniq각 줄의 처음 32자만 비교합니다.

이것은 인쇄됩니다모두고유하지 않은 md5sum이 있는 파일. 즉, 중복됩니다.

참고: 이는 A/ 또는 B/에 관계없이 중복 파일을 감지하므로 /A/subdir1/fileA/subdir2/otherfile가 동일하면 계속 인쇄됩니다. 중복된 내용이 여러 개인 경우 모두 인쇄됩니다.

awk '{print $2}'예를 들어, 또는 등으로 cut파이프 하여 출력에서 ​​md5sum을 제거할 수 있습니다. 나중에 sed연관 배열(일명 '해시')에 대한 유용한 키이기 때문에 출력에 남겨 두었습니다 . 처리.awkperl

답변2

내 생각엔 이것이 당신을 더 가까워지게 할 것 같아요. B의 결과라는 모든 파일과 비교하여 A의 결과라는 모든 파일에 대한 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" ;

업데이트:

추가 피드백을 받은 후 다른 스크립트를 사용하여 디렉터리의 모든 파일을 무조건 비교 합니다 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" ;

관련 정보