많은 하위 폴더와 파일이 있는 폴더("orig"라고 함)와 다른 폴더 구조에 백업으로 배치된 많은 동일한 파일이 있는 다른 폴더("backup"이라고 함)가 있습니다. "orig"에 아직 존재하지 않는 "backup"의 모든 파일을 나열하여 "orig"의 올바른 하위 볼륨에 넣고 "backup"을 삭제할 수 있도록 하고 싶습니다. 파일 이름과 크기를 비교하면 충분합니다.
이전에도 비슷한 질문을 하신 분이 계시는데, 추천해드리는 해결방법은 입니다 diff -qr orig/ backup/
. 그러나 이것을 시도했을 때 명령이 한 폴더에는 표시되고 다른 폴더에는 표시되지 않았지만 파일은 표시되지 않았기 때문에 재귀가 작동하지 않는다는 것을 발견했습니다. 여기에 예가 있습니다. 먼저 각각 하위 폴더와 파일이 포함된 두 개의 폴더를 만듭니다. 각 하위 폴더와 파일에는 서로 다른 콘텐츠가 있습니다.
$ mkdir orig
$ mkdir backup
$ mkdir orig/1
$ mkdir backup/2
$ echo 'blah' > orig/1/test.txt
$ ls orig/1
test.txt
$ echo 'blah1' > backup/2/test1.txt
이제 "-qr" 옵션을 사용하여 비교합니다.
$ diff -qr orig/ backup/
Only in orig/: 1
Only in backup/: 2
다음 중 하나의 하위 폴더로 이동하면 해당 폴더에서 파일을 찾을 수 있습니다.
$ diff -r orig/1 backup/
Only in backup/: 2
Only in orig/1: test.txt
실제로 "-qr"이 있든 없든 동일한 동작이 발생합니다. 이것은 버그입니까, 아니면 차이점을 오해하고 있습니까? 저는 diff(GNU diffutils) 3.7을 사용하고 있습니다.
내 문제를 해결하는 방법에 대한 다른 제안이 있으면 크게 감사하겠습니다(예: 간단한 Python 스크립트).
답변1
Python을 사용하여 문제를 해결하는 방법을 찾았습니다.
import filecmp
import os.path
def find_unique_files(path_orig, path_duplicates, ommit_in_orig=[]):
"""
Crawls all subfolders of path_duplicates and
returns list of files (incl. paths) that occur
in path_duplicates but no-where in path_orig,
except for folders listed in ommit_in_orig.
Do not forget to add trailing '/' at the end of paths.
Arguments:
path_orig -- string
path_duplicates -- string
ommit_in_orig -- list of strings
Returns:
list of strings indicating paths to files.
Example:
find_unique_files('/home/user/project/',
'/home/user/project/backups/',
ommit_in_orig=['/home/user/project/backups/',
'/home/user/project/temp/'])
"""
unique_files = []
for folder, subfolders, files in os.walk(path_duplicates):
print(folder, end='\r')
for file in files:
unique = 1
filepath = os.path.join(folder,file)
for folder1, subFolders1, files1 in os.walk(path_orig):
# Check if folder1 is a subfolder of ommit_in_orig
ommit = [s for s in ommit_in_orig if s.lower() in folder.lower()]
if len(ommit) == 0:
if file in files1:
filepath1 = os.path.join(folder1, file)
if filecmp.cmp(filepath,filepath1):
# File is identical
unique = 0
if unique == 1:
unique_files.append(filepath)
return unique_files
path_orig = 'orig/'
path_duplicates = 'backup/'
find_unique_files(path_orig, path_duplicates)