다른 파일을 열지 않고 비교하는 방법은 무엇입니까?

다른 파일을 열지 않고 비교하는 방법은 무엇입니까?

두 개의 디렉터리 A와 B가 있으며 각각에는 많은 하위 디렉터리가 있습니다.

geom001, geom002 ....etc

각 하위 디렉터리에는 results.txt라는 파일이 포함되어 있습니다. A의 모든 파일을 B의 모든 파일과 열지 않고 비교하고, B의 하나 이상의 파일과 유사한 A의 파일이 하나 이상 있는지 확인하고 싶습니다. 다음 명령을 사용하여 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

나는 이것이 당신을 더 가깝게 만들 것이라고 생각합니다. 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" ;

고쳐 쓰다:

다음은 추가 피드백을 받은 후 무조건 디렉터리의 모든 파일을 다음 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" ;

관련 정보