>

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

geom001, geom002 ....etc

각 하위 디렉토리에는 results라는 파일이 있습니다. 파일을 열지 않고 A의 각 파일과 B의 각 파일을 비교하고 A의 파일이 B의 하나 이상의 파일과 유사한 지 확인하고 싶습니다. 루프에서 다음과 같은 명령을 사용하여 모든 파일을 검색하려면 어떻게해야합니까?

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  프로그램 출력은 16 진수를 사용합니다. 그래서 우리는 -w32 를 사용합니다   uniq 의 옵션  각 줄의 처음 32 자만 비교하라는 명령입니다.

    이것은 고유하지 않은 md5sum으로모든파일을 인쇄합니다. 즉 중복됩니다.

    참고 : A/또는 B/위치에 관계없이 중복 파일을 감지하므로 /A/subdir1/file  그리고 A/subdir2/otherfile  동일하지만 여전히 인쇄됩니다. 사본이 여러 개인 경우 모두 인쇄됩니다.

    예 : awk '{print $2}' 에 배관하여 출력에서 ​​md5sum을 제거 할 수 있습니다.  또는 cut  또는 sed   awk 의 연관 배열 (일명 '해시')에 유용한 키이기 때문에 출력에 남겨 두었습니다.  또는 perl  추가 처리를 위해 기타 등등.

  • 답변 # 2

    이것이 당신을 닫을 것이라고 생각합니다. 결과 이름이 B 인 모든 파일과 비교하여 결과 이름이 A 인 모든 파일의 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" ;
    
    

관련 자료

  • 이전 grep - 일치/일치하지 않는 패턴의 개수를 인쇄하고 여러 패턴을 한 줄로 분리하여 인쇄하는 방법
  • 다음 sed - 대체 텍스트가 파일에있을 때 한 텍스트 블록을 다른 텍스트 블록으로 교체