두 폴더를 어떻게 비교하고 차이를 세 번째 폴더로 복사합니까?


23

세 개의 폴더가 있습니다 :

  • 현재 파일을 포함하는 current 폴더
  • 동일한 파일의 이전 버전을 포함하는 old 폴더
  • 빈 폴더 인 폴더 차이

어떻게 비교 할 현재 와 다른 (또는 완전히 새로운)있는 파일 복사 현재차이를 ?


나는 모든 것을 수색했으며 그것이 해결해야 할 간단한 것 같지만 특정 예제에서 작동하도록 할 수는 없습니다. 대부분의 소스는 rsync 사용을 제안 했으므로 다음 명령으로 끝났습니다.

rsync -ac --compare-dest=../old/ new/ difference/

이 그러나 무엇을, 모든 파일이 복사입니다 차이 도,과 동일 것들 오래 .

도움이되는 경우 (명령이 훌륭하고 결함이 다른 곳에있을 수 있음), 이것이 이것을 테스트 한 방법입니다.

  1. 세 개의 폴더를 만들었습니다.
  2. 나는 오래된 내용이 다른 여러 텍스트 파일을 만들었습니다 .
  3. 파일을 old 에서 new로 복사했습니다 .
  4. 파일에서 일부 파일의 내용을 변경하고 몇 가지 추가 파일을 추가했습니다.
  5. 위의 명령을 실행하고 결과가 다른지 확인했습니다 .

지난 며칠 동안 해결책을 찾고 있었고 실제로 도움을 주셔서 감사합니다. 반드시 rsync를 사용해야 할 필요는 없지만 가능한 경우 내가 뭘 잘못하고 있는지 알고 싶습니다.



@wingedsubmariner 연결된 질문에서 허용되는 답변은 OP가 질문하는 명령이므로 중복이라고 생각하지 않습니다.
Bernhard

@Bernhard 아, 내 나쁜. 원래 질문을 오해 한 것 같습니다.
wingedsubmariner

@wingedsubmariner 걱정할 필요가 없습니다. "가능한 것"이라고 말했는데 매우 비슷해 보입니다 :)
Bernhard

답변:


7

rsync 또는 diff와 같은 기존 Linux 명령으로 수행 할 수 있는지 확실하지 않습니다. 그러나 파이썬에는 파일 비교를 위해 "filecmp"모듈이 있으므로 Python을 사용하여 자체 스크립트를 작성해야했습니다. 개인 사이트 ( http://linuxfreelancer.com/) 에 전체 스크립트 및 사용법을 게시했습니다.

사용법은 간단합니다. 순서대로 새 디렉토리, 이전 디렉토리 및 차이 디렉토리의 절대 경로를 지정하십시오.

#!/usr/bin/env python

import os, sys
import filecmp
import re
from distutils import dir_util
import shutil
holderlist=[]

def compareme(dir1, dir2):
    dircomp=filecmp.dircmp(dir1,dir2)
    only_in_one=dircomp.left_only
    diff_in_one=dircomp.diff_files
    dirpath=os.path.abspath(dir1)
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in only_in_one]
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in diff_in_one]
    if len(dircomp.common_dirs) > 0:
        for item in dircomp.common_dirs:
            compareme(os.path.abspath(os.path.join(dir1,item)), os.path.abspath(os.path.join(dir2,item)))
        return holderlist

def main():
 if len(sys.argv) > 3:
   dir1=sys.argv[1]
   dir2=sys.argv[2]
   dir3=sys.argv[3]
 else:
   print "Usage: ", sys.argv[0], "currentdir olddir difference"
   sys.exit(1)

 if not dir3.endswith('/'): dir3=dir3+'/'

 source_files=compareme(dir1,dir2)
 dir1=os.path.abspath(dir1)
 dir3=os.path.abspath(dir3)
 destination_files=[]
 new_dirs_create=[]
 for item in source_files:
   destination_files.append(re.sub(dir1, dir3, item) )
 for item in destination_files:
  new_dirs_create.append(os.path.split(item)[0])
 for mydir in set(new_dirs_create):
   if not os.path.exists(mydir): os.makedirs(mydir)
#copy pair
 copy_pair=zip(source_files,destination_files)
 for item in copy_pair:
   if os.path.isfile(item[0]):
    shutil.copyfile(item[0], item[1])

if __name__ == '__main__':
 main()

21

나는 내 경우에 문제가 무엇인지 알아 냈습니다.

필자가 비교 한 파일에는 서로 다른 타임 스탬프가있었습니다. rsync가 파일을 복사 할 때 타임 스탬프를 유지하려고했기 때문에 -a 인수를 사용해서는 안됩니다 . 나를 위해 일한 명령은 다음과 같습니다.

rsync -rvcm --compare-dest=../old/ new/ difference/

나는 이것을 -a (아카이브) 옵션으로 테스트한다고 생각한다 rsync -a. 파일을 처음에 (또는 cp에 상응하는) "복사"한 다음 삭제하거나 수정해야했다. (나는 그것이 무엇을하고 있는지 생각하지 않고 일관성이 있음을 알고 있기 때문에 rsync를 고수하고 싶다.) 나는 그것이 원래 명령으로 작동했을 것이라고 생각한다. -a 옵션에는 -c (체크섬 비교) 대신 -t (타임 스탬프 비교)가 포함됩니다.
현인

2
내 의견으로는이 답변은 훨씬 간단하기 때문에 받아 들여야합니다. 또한 명령은 old/and에 대한 전체 경로를 제공했을 때만 작동했습니다 new/.
야마 네코

주의해야 할 점은 비교-이명 령은 그 실제의 최종 도착 내부에서 본의 차이에 대한 상대 경로 여야합니다 것 같다
라이언 윌리엄스

1

이것은 일부 독자들에게 도움이 될 수 있습니다. Windows에서는 오래된 작은 프리웨어 프로그램 인 Third Dir이 여기에서 요구되는 내용을 정확하게 수행합니다. Robert Vašíček 개발자를 통해 더 이상 제공되지 않습니다. 그러나 나는 온라인으로 일부 저장소를 통해 찾을 수 있다고 확신합니다.

그의 사이트에 남아있는 개발자 설명은 다음과 같습니다.

세 번째 디렉터리 : 특이한 디렉터리 동기화 – 다른 파일이 세 번째 디렉터리에 복사됩니다. 고정 디스크의 거대한 디렉토리 트리에서 임시 폴더로 새 사진 또는 편집 된 사진을 추출한 다음 아카이브 CD에 추가하는 것이 매우 유용합니다 (참고-원본 파일은 CD와 비교). 버전 1.4, 크기 23kB 작성 2005-02-12.

이력 : 버전 1.14-수만 개의 파일을 비교할 때 더 효율적입니다.


0

Thane가 Yamaneko를 추가 한 rsync 방식은 훌륭하게 작동하지만 빈 디렉토리는 그대로 둡니다. 나를 위해 최종 솔루션은 두 단계로 이루어졌습니다. 먼저 전체 경로로 rsync를 호출 한 다음 find 명령을 사용하여 빈 디렉토리를 모두 제거하십시오.

rsync -rvcm --compare-dest=/tmp/org/ /tmp/new/ /tmp/difference/
find /tmp/difference/ -d -type d -empty -exec rmdir {} \; -print

--links 옵션을 사용하더라도 rsync는 기호 링크를 유지하지 않고 대신 대상 데이터를 복사했습니다.


대신을 -empty -exec rmdir {} \;사용할 수 있습니다 -empty -delete.
mivk

-3

나는 많은 트릭을 수행 할 수있는 이중 패널 XY 탐색기 (상업용)를 사용하며 이는 그중 하나입니다. Current한 창에서 열고 다른 창에서 Old를 엽니 다 . 현재 분할 창을 활성화하십시오. 분할 창 > 동기화 선택으로 이동 하십시오. 선택할 수있는 5 가지 옵션이 있습니다.

  1. 일치 (둘 다에 나열)
  2. 고유 항목 (활성 창에서)
  3. 최신 (활성 창에서)
  4. 고유하고 새로운 파일 (활성 창에서)
  5. 선택됨 (다른 창에서 선택된 것)

이제 결과 선택 Current을 원하는 위치로 복사 할 수 있습니다 . mailfolders이전 설치와 최신 설치 를 비교하는 데 사용했습니다 . 폴더 구조는 상당히 복잡했지만 (거의) 모두 mbs-files고유 한 번호를 가졌습니다.

그래서 mbs-files이전 루트 mailfolder(한 창)와 최신 (다른 창)에서 검색을 수행하고 각 창 ( 동기화 선택 고유) 의 검색 결과를 비교하여 누락 된 메일을 찾습니다. 다시 설치)! 많은 옵션을 설정할 수도 있습니다.


1
비표준 소프트웨어에 대해 이야기하는 경우 링크를 포함시켜야합니다. XYplorer 를 의미한다면 OP에 전혀 도움이되지 않습니다.
Anthon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.