파일의 내용이 아닌 디렉토리 비교


21

diff -r을 사용하면이 작업을 수행 할 수 있지만 diff가 파일의 내용을 확인하므로 시간이 오래 걸립니다.

두 파일이 크기, 마지막 수정 등에 대해 동일하다는 것을 결정하는 것을 원합니다.하지만 파일을 비트 단위로 검사하지 않습니다 (예 : 비디오가 너무 오래 걸립니다)

다른 방법이 있습니까?

답변:


20

rsync는 기본적으로 파일 메타 데이터 만 비교합니다.

rsync -n -a -i --delete source/ target/

설명:

  • -n 실제로 복사하거나 삭제하지 마십시오 <-이것은 중요합니다 !! 1
  • -a 타임 스탬프 및 속성과 같은 파일의 모든 메타 데이터 비교
  • -i 파일 당 한 줄의 정보를 인쇄
  • --delete 소스에없는 파일도보고

참고 : 디렉토리 이름에 슬래시를 추가해야합니다. 이것은 rsync 것입니다.

동일한 파일에 대해 인쇄 된 줄을 보려면 -i두 번 제공하십시오.

rsync -n -a -ii --delete source/ target/

출력 예 :

*deleting   removedfile   (file in target but not in source)
.d..t...... ./            (directory with different timestamp)
>f.st...... modifiedfile  (file with different size and timestamp)
>f+++++++++ newfile       (file in source but not in target)
.f          samefile      (file that has same metadata. only with -ii)

rsync는 메타 데이터 만 비교합니다. 즉, 파일 내용은 변경되었지만 메타 데이터는 그대로 유지 된 경우 rsync에서 해당 파일이 같다고보고합니다. 이것은 가능성이 거의없는 시나리오입니다. 따라서 메타 데이터가 같으면 데이터가 동일하거나 파일 데이터를 비트 단위로 비교해야한다고 신뢰하십시오.

보너스 : 진행 정보는 여기를 참조하십시오 : rsync를 마치기 위해 남은 시간이나 일을 예상하십니까?


1
슬래시 source/target/둘 다 매우 중요합니다! (그들이 없으면 소스와 대상 디렉토리 이름을 하위 파일 이름과 비교하므로 모든 파일 이름이 달라집니다.)
peschü

나는 당신의 의견을 더 일찍 읽었 으면 좋겠다. 이것은 매우 중요하다! 소스에서만 슬래시를 생략 한 다음 대상의 파일이로 표시되지 않는 이유가 궁금 *deleting했지만 소스 파일 만 표시되었습니다. 슬래시는 실수로 잊어 버린 다음 그럴듯하지만 잘못된 출력을 얻습니다.
user643011

3

-q( --brief)와 함께 diff -r( diff -qr) 옵션을 사용하십시오 . 로부터 infoGNU 페이지 diff:

1.6 어떤 파일이 다른지 요약

파일이 다른지 여부 만 확인하고 차이점이 무엇인지 상관하지 않는 경우 요약 출력 형식을 사용할 수 있습니다. 이 형식에서 diff' simply reports whether files differ. The--brief '(`-q') 옵션 은 파일 간의 차이점을 표시하는 대신 이 출력 형식을 선택합니다.

이 형식은 두 디렉토리의 내용을 비교할 때 특히 유용합니다. `diff '는 차이가 있다는 것을 알게 되 자마자 파일 분석을 중단 할 수 있기 때문에 일반적인 라인 별 비교보다 훨씬 빠릅니다.

이것은 한 줄씩 비교하지 않고 파일 전체를 비교하여 프로세서 속도를 크게 향상시킵니다 (찾고있는 내용).


1
-q의 문제는 정상을 비교하고 차이가 발견되면 (정상 모드 인 경우 비교를 계속 유지) 큰 파일이 동일하면 많이 지속된다는 것입니다.
eez0

2

다음은 파일 이름, mtimes 및 파일 크기가 모두 같은지 확인하는 빠른 파이썬 스크립트입니다.

import os
import sys

def getStats(path):
    for pathname, dirnames, filenames in os.walk(path):
        for filename in ( os.path.join(pathname, x) for x in filenames ):
            stat = os.stat(filename)
            yield filename[len(path):], stat.st_mtime, stat.st_size

sys.exit(tuple(getStats(sys.argv[1])) != tuple(getStats(sys.argv[2])))

1

두 파일 시스템 브랜치의 파일이 다른지 (파일 내부를 보지 않고) 다른지 알아야하는 경우 다음과 같이 할 수 있습니다.

find /opt/branch1 -type f | sort | xargs -i md5sum {} >/tmp/branch1;
find /opt/branch2 -type f | sort | xargs -i md5sum {} >/tmp/branch2;
diff /tmp/branch1 /tmp/branch2;

HTH


0

Chris Down의 스크립트를 기반으로이 스크립트는 좀 더 "시각적"입니다. 두 가지 인자로 호출 folder1하고 folder2, 제 폴더를 걸어 각각의 파일에 대해 상기 제 폴더에 대응하는 파일을 검색한다. 경로가 발견되면 상대 경로가 녹색으로 인쇄되고 수정 된 시간이나 크기가 다르면 노란색으로 인쇄되고 찾을 수 없으면 빨간색으로 인쇄됩니다.

#!/usr/bin/env python

import os
import sys
from termcolor import colored

def compare_filestats(file1,file2):
    """
    Compares modified time and size between two files.
    Return:
        -1 if file1 or file2 does not exist
         0 if they exist and compare equal
         1 if they have different modified time, but same size
         2 if they have different size, but same modified time
         3 if they have different size, and different modified time
    """

    if not os.path.exists(file1) or not os.path.exists(file2):
        return -1

    stat1 = os.stat(file1)
    stat2 = os.stat(file2)

    return (stat1.st_mtime != stat2.st_mtime) \
        + 2*(stat1.st_size != stat2.st_size)

def compare_folders(folder1,folder2):
    """
    folder1: serves as reference and will be walked through
    folder2: serves as target and will be querried for each file in folder1

    Prints colored status for each file in folder1:
        missing: file was not found in folder2 
        mtime  : modified time is different
        size   : filesize is different
        ok     : found with same filestats
    """
    for dirpath, dirnames, filenames in os.walk(folder1):
        for file1 in ( os.path.join(dirpath, x) for x in filenames ):
            relpath = file1[len(folder1):]
            file2 = os.path.join( folder2, relpath )
            comp = compare_filestats(file1,file2)

            if comp < 0:
                status = colored('[missing]','red')
            elif comp == 1:
                status = colored('[mtime  ]','yellow')
            elif comp >= 2:
                status = colored('[size   ]','yellow')
            else:
                status = colored('[ok     ]','green')

            print status, relpath

if __name__ == '__main__':
    compare_folders(sys.argv[1],sys.argv[2])

이것은 두 폴더가 동일한 지 여부를 결정하기에 충분 하지 않으므로 두 가지 방법으로 폴더를 모두 실행해야합니다. 실제로 폴더가 동일한 지 여부 를 알고 싶다면 Chris의 스크립트가 더 좋습니다. 한 폴더에서 다른 폴더로 누락되거나 다른 것이 무엇인지 알고 싶다면 내 스크립트가 알려줍니다.

참고 : termcolor가 설치되어 있어야 pip install termcolor합니다.


0

파일에 대한 구조와 기본 정보 만 비교하려면 다음과 같이 해보십시오.

diff <(cd $DIR1 && ls -laR) <(cd $DIR2 && ls -laR)

나는 그것을 테스트하지 않았으므로 모든 편집을 환영합니다 :)


2
디렉토리 이름 자체도 결과에 있으므로 작동하지 않습니다.
Chris Down

디렉토리 이름이있는 첫 번째 열을 제외하면 어떻게됩니까? <(ls -laR | awk '{$ 1 = ""; print}')
Volodymyr

모든 행이 디렉토리 이름 인 것은 아니므로 제대로 작동하지 않습니다.
Chris Down

각각 <()고유 한 환경이 있다는 사실을 활용하십시오 . 편집했습니다.
CVn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.