다운로드 폴더, 바탕화면, 외장하드까지 여기저기 저장하다 보면 같은 파일이 이름만 다르게(또는 똑같이) 여러 군데에 중복 저장되는 경우가 많습니다. 파일명만 보고 지우자니 실수로 다른 파일을 지울까 불안하고, 하나하나 열어서 비교하기엔 시간이 너무 걸립니다. 이번 글에서는 파일 내용을 기준으로 진짜 중복 파일만 정확하게 찾아주는 파이썬 스크립트를 만들어보겠습니다.
왜 파일명이 아니라 내용으로 비교해야 할까
“사진.jpg”와 “사진(1).jpg”처럼 이름은 다르지만 내용이 완전히 같은 파일이 있는가 하면, 반대로 이름은 같아도 내용이 다른 파일도 있습니다. 그래서 파일명 대신 파일의 해시값(MD5)을 계산해서 비교하는 방식이 훨씬 정확합니다. 내용이 1비트라도 다르면 해시값도 달라지기 때문에, 해시값이 같은 파일은 사실상 100% 동일한 파일이라고 볼 수 있습니다.
중복 파일을 찾아주는 파이썬 스크립트
아래 스크립트는 지정한 폴더들을 하위 폴더까지 전부 훑으면서 파일 해시값을 계산하고, 같은 해시값을 가진 파일들을 그룹으로 묶어 보여줍니다.
import os, hashlib
from collections import defaultdict
TARGET_DIRS = [r"C:\Users\사용자명\Downloads", r"C:\Users\사용자명\Desktop"]
def get_file_hash(filepath, block_size=65536):
hasher = hashlib.md5()
with open(filepath, "rb") as f:
for block in iter(lambda: f.read(block_size), b""):
hasher.update(block)
return hasher.hexdigest()
def find_duplicates(dirs):
hash_map = defaultdict(list)
for directory in dirs:
for root, _, files in os.walk(directory):
for filename in files:
filepath = os.path.join(root, filename)
try:
file_hash = get_file_hash(filepath)
hash_map[file_hash].append(filepath)
except (PermissionError, FileNotFoundError):
continue
return {h: paths for h, paths in hash_map.items() if len(paths) > 1}
if __name__ == "__main__":
duplicates = find_duplicates(TARGET_DIRS)
for file_hash, paths in duplicates.items():
print(f"[중복 발견] 총 {len(paths)}개")
for p in paths:
print(f" - {p}")
찾은 중복 파일을 자동으로 정리하기
중복 목록을 눈으로 확인만 하고 끝내기보다, 각 그룹에서 가장 먼저 발견된 파일은 남기고 나머지는 별도의 “_dupes” 폴더로 옮겨서 나중에 검토 후 지우는 방식이 안전합니다. 위 find_duplicates 함수 결과를 활용해 아래 코드를 이어서 실행하면 됩니다.
import shutil
DUPE_DIR = r"C:\Users\사용자명\Desktop\_dupes"
def move_duplicates(duplicates):
os.makedirs(DUPE_DIR, exist_ok=True)
for paths in duplicates.values():
for filepath in paths[1:]:
target = os.path.join(DUPE_DIR, os.path.basename(filepath))
shutil.move(filepath, target)
print(f"이동 완료: {filepath} -> {target}")
실행 방법
- 두 코드를
find_duplicates.py파일 하나에 순서대로 저장합니다. TARGET_DIRS에 검사하고 싶은 폴더 경로를 원하는 만큼 추가합니다.- 터미널에서
python find_duplicates.py를 실행하면 중복 파일 목록이 출력됩니다. - 결과가 원하는 대로 나오면
move_duplicates(duplicates)호출을 코드 마지막에 추가해 실제로 이동시킵니다.
사용할 때 주의할 점
- 큰 파일이 많으면 해시 계산에 시간이 걸릴 수 있습니다. 폴더 범위를 필요한 곳으로 좁혀서 실행하세요.
- 바로 삭제하지 말고 반드시 “_dupes” 폴더로 옮긴 뒤, 내용을 확인하고 나서 지우는 것을 권장합니다.
- 시스템 폴더나 프로그램 설치 폴더는 검사 대상에서 제외하세요. 실행 중인 프로그램 파일이 중복으로 인식되어 옮겨지면 프로그램이 망가질 수 있습니다.
파일명이 아니라 내용 기준으로 비교하기 때문에 안심하고 정리할 수 있습니다. 다음 글에서는 이번 스크립트와 짝을 이루는, 오래된 파일을 기준을 정해 자동으로 삭제하거나 백업하는 방법을 다뤄보겠습니다.