중복 파일 삭제 스크립트를 돌렸다가 식은땀 흘린 날

이미지
중복 파일 삭제 스크립트를 돌렸다가 식은땀 흘린 날 이 블로그의 중복 파일 자동 삭제 편 과 파일명 일괄 변경 편 을 보면 공통적으로 "DRY_RUN"이라는 안전장치가 들어 있습니다. 실제 삭제나 변경 전에 미리보기부터 하도록 만든 이 습관은, 사실 처음부터 있던 게 아니라 한 번의 아찔한 경험 뒤에 생긴 것입니다. 당시 상황은 이랬습니다. 다운로드 폴더가 오래 방치되어 있어 용량을 확인해보니 중복 파일이 상당히 많았고, "파일 해시값을 비교해서 중복이면 자동으로 지우는" 스크립트를 처음 짜서 바로 실행했습니다. 사건 발생 — 실행 버튼을 누른 직후 처음 짠 코드는 대략 이런 형태였습니다. import hashlib from pathlib import Path from collections import defaultdict folder = Path(r"C:\Users\내이름\Downloads") hash_map = defaultdict(list) def get_hash(filepath): h = hashlib.md5() with open(filepath, "rb") as f: h.update(f.read()) return h.hexdigest() for file in folder.rglob("*"): if file.is_file(): hash_map[get_hash(file)].append(file) # 중복이면 첫 번째만 남기고 나머지 삭제 for files in hash_map.values(): if len(files) > 1: for f in files[1:]: f.unlink() # ← 바로 삭제 실행 print(f"삭제: {f.name}") 실행하자마자 터미널에 "삭제: ......

중요 엑셀 실수로 덮어썼을 때 끝! 파이썬으로 자동 백업·버전 관리하기

중요 엑셀 실수로 덮어썼을 때 끝! 파이썬으로 자동 백업·버전 관리하기 (완성 코드 공개)

파이썬으로 엑셀 파일을 자동으로 백업하고 버전 관리하는 모습


"어제까지 있던 데이터가 오늘 보니 사라졌는데 누가 언제 지웠는지 모르겠다", "수정하다가 실수로 저장을 눌러서 이전 내용을 영영 잃어버렸다", "여러 명이 같은 파일을 작업하는데 누가 무엇을 바꿨는지 추적이 안 된다"…

중요한 엑셀 파일은 한 번의 실수로 되돌릴 수 없는 손실이 생길 수 있습니다. 파이썬을 한 번만 세팅해두면 파일이 변경될 때마다 자동으로 버전별 백업을 만들고, 언제 어떤 변경이 있었는지 이력을 기록해서 필요할 때 이전 버전으로 즉시 되돌릴 수 있습니다.


1단계: 준비물 설치

파이썬이 설치되어 있어야 합니다. 없다면 python.org에서 최신 버전을 받아 설치하세요. 설치 시 반드시 "Add Python to PATH"에 체크해야 합니다.

변경 감지에 필요한 라이브러리를 설치합니다. 터미널(윈도우: CMD 또는 파워셸)을 열고 아래 명령어를 실행하세요:

pip install watchdog pandas openpyxl

watchdog은 파일이 수정되는 순간을 실시간으로 감지하는 라이브러리입니다. pandasopenpyxl은 변경 전후 데이터를 비교해 이력을 기록하는 데 사용합니다.

💡 이 코드로 할 수 있는 것: 지정한 엑셀 파일이 저장될 때마다 자동으로 타임스탬프가 포함된 백업을 생성하고, 변경 이력을 텍스트 로그로 남깁니다. 보관할 백업 개수를 제한해 저장 공간도 관리합니다. 필요할 때 특정 시점의 백업으로 즉시 복원할 수 있습니다.

2단계: 완성 코드 — 실시간 자동 백업 감시

아래 코드를 그대로 복사해서 메모장에 붙여넣고, excel_watcher.py로 저장하세요. 저장 시 파일 형식은 "모든 파일", 인코딩은 UTF-8로 설정합니다.

import shutil
import time
from pathlib import Path
from datetime import datetime
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# ① 설정
WATCH_FOLDER  = r"C:\Users\내이름\Desktop\중요엑셀파일"       # ← 감시할 폴더
BACKUP_FOLDER = r"C:\Users\내이름\Desktop\엑셀백업저장소"     # ← 백업 저장 폴더
LOG_FILE      = r"C:\Users\내이름\Desktop\엑셀백업저장소\변경이력.txt"
MAX_VERSIONS  = 20    # ← 파일별 보관할 최대 버전 수 (초과 시 오래된 것부터 삭제)
TARGET_EXT    = {".xlsx", ".xlsm"}   # ← 감시할 확장자

# ② 백업 폴더 준비
backup_dir = Path(BACKUP_FOLDER)
backup_dir.mkdir(parents=True, exist_ok=True)

def log_change(message):
    """변경 이력을 로그 파일에 기록"""
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(LOG_FILE, "a", encoding="utf-8") as f:
        f.write(f"[{now}] {message}\n")
    print(f"  {message}")

def cleanup_old_versions(file_stem):
    """오래된 백업 버전 정리 (MAX_VERSIONS 초과 시)"""
    versions = sorted(backup_dir.glob(f"{file_stem}_*"),
                      key=lambda f: f.stat().st_mtime)
    while len(versions) > MAX_VERSIONS:
        old = versions.pop(0)
        old.unlink()
        log_change(f"🗑 오래된 버전 삭제: {old.name}")

# ③ 파일 변경 감지 핸들러
class ExcelChangeHandler(FileSystemEventHandler):
    def __init__(self):
        self.last_backup = {}   # 중복 이벤트 방지용 (파일별 마지막 백업 시각)

    def on_modified(self, event):
        if event.is_directory:
            return

        file_path = Path(event.src_path)
        if file_path.suffix.lower() not in TARGET_EXT:
            return

        # 같은 파일에 대해 2초 이내 중복 이벤트 무시 (저장 시 여러 이벤트 발생 방지)
        now = time.time()
        if file_path.name in self.last_backup:
            if now - self.last_backup[file_path.name] < 2:
                return
        self.last_backup[file_path.name] = now

        # 백업 생성
        timestamp  = datetime.now().strftime("%Y%m%d_%H%M%S")
        backup_name = f"{file_path.stem}_{timestamp}{file_path.suffix}"
        backup_path = backup_dir / backup_name

        try:
            time.sleep(0.5)   # 저장이 완전히 끝날 때까지 잠시 대기
            shutil.copy2(file_path, backup_path)
            log_change(f"✔ 백업 생성: {file_path.name} → {backup_name}")
            cleanup_old_versions(file_path.stem)
        except Exception as e:
            log_change(f"✘ 백업 실패: {file_path.name} → {e}")

# ④ 감시 시작
event_handler = ExcelChangeHandler()
observer = Observer()
observer.schedule(event_handler, WATCH_FOLDER, recursive=False)
observer.start()

print(f"▶ 엑셀 자동 백업 감시 시작: {WATCH_FOLDER}")
print(f"  백업 저장 위치: {BACKUP_FOLDER}")
print(f"  종료하려면 Ctrl+C를 누르세요.\n")

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
    print("\n  감시를 종료합니다.")
observer.join()

3단계: 실행 방법

  1. 코드 ① 설정의 WATCH_FOLDER에 감시할 엑셀 파일이 있는 폴더 경로를 입력합니다.
  2. BACKUP_FOLDER에 백업을 저장할 폴더 경로를 입력합니다.
  3. MAX_VERSIONS에 파일별로 보관할 최대 백업 개수를 입력합니다.
  4. 터미널에서 아래 명령어로 실행합니다. 실행 후에는 터미널 창을 계속 열어둡니다:
python excel_watcher.py

실행 중 감시 대상 폴더의 엑셀 파일을 수정하고 저장하면 터미널에 이렇게 출력됩니다:

▶ 엑셀 자동 백업 감시 시작: C:\Users\내이름\Desktop\중요엑셀파일
  백업 저장 위치: C:\Users\내이름\Desktop\엑셀백업저장소
  종료하려면 Ctrl+C를 누르세요.

  [2026-06-22 09:15:32] ✔ 백업 생성: 거래처현황.xlsx → 거래처현황_20260622_091532.xlsx
  [2026-06-22 10:42:18] ✔ 백업 생성: 거래처현황.xlsx → 거래처현황_20260622_104218.xlsx

파일을 저장할 때마다 자동으로 타임스탬프가 포함된 백업 파일이 생성되고, 변경 이력이 로그 파일에 누적됩니다.


4단계: 자주 발생하는 오류와 해결법

오류 1: 같은 저장에 백업이 2~3개씩 중복 생성됨

엑셀 저장 시 임시 파일 생성 등으로 여러 이벤트가 발생하는 경우입니다. 코드에 이미 2초 이내 중복 방지 로직이 포함되어 있습니다. 여전히 중복된다면 time.sleep(2)로 대기 시간을 늘려보세요.

오류 2: ModuleNotFoundError: No module named 'watchdog'

설치가 제대로 되지 않은 경우입니다. 아래 명령어로 다시 시도하세요.

python -m pip install watchdog

오류 3: 백업이 생성되지 않음

엑셀 파일이 WATCH_FOLDER에 직접 있는지 확인하세요. 하위 폴더는 감시 대상이 아닙니다. 하위 폴더까지 감시하려면 observer.schedule(event_handler, WATCH_FOLDER, recursive=True)로 변경하세요.


응용: 이전 버전으로 복원하기

백업된 버전 목록을 확인하고 원하는 시점으로 복원하는 코드입니다. 아래 코드를 restore.py로 저장하세요.

import shutil
from pathlib import Path

BACKUP_FOLDER = r"C:\Users\내이름\Desktop\엑셀백업저장소"
RESTORE_TARGET = r"C:\Users\내이름\Desktop\중요엑셀파일\거래처현황.xlsx"   # ← 복원할 원본 위치
FILE_STEM = "거래처현황"   # ← 확인할 파일 이름 (확장자 제외)

backup_dir = Path(BACKUP_FOLDER)
versions   = sorted(backup_dir.glob(f"{FILE_STEM}_*"),
                    key=lambda f: f.stat().st_mtime, reverse=True)

print(f"  '{FILE_STEM}' 백업 버전 목록 (최신순):\n")
for i, v in enumerate(versions):
    mtime = v.stat().st_mtime
    from datetime import datetime
    time_str = datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S")
    print(f"  [{i}] {v.name}  ({time_str})")

# 복원할 버전 번호 선택
choice = int(input("\n복원할 버전 번호를 입력하세요: "))
selected = versions[choice]

shutil.copy2(selected, RESTORE_TARGET)
print(f"\n✅ 완료! '{selected.name}' 버전으로 복원했습니다.")
💡 이전 게시글과 결합하면: 폴더 자동 백업 편과 결합하면 백업소 자체를 외장 하드에 추가로 보관할 수 있고, 텔레그램 자동 발송 편과 결합하면 백업이 생성될 때마다 알림을 받는 것도 가능합니다.

핵심 요약

  • 준비물: Python + watchdog + pandas + openpyxl 설치 (pip install watchdog pandas openpyxl)
  • 설정: WATCH_FOLDER, BACKUP_FOLDER, MAX_VERSIONS 수정
  • 실행: 터미널에서 python excel_watcher.py 입력 후 계속 실행 상태 유지
  • 결과: 파일 저장마다 타임스탬프 백업 자동 생성, 변경 이력 로그 누적, 오래된 버전 자동 정리
  • 복원: restore.py로 원하는 시점 버전을 선택해 즉시 복원

이 코드를 응용하면 여러 파일을 동시에 감시하거나, 변경 전후 데이터를 비교해 무엇이 바뀌었는지 자동으로 분석하는 것도 가능합니다.

이 블로그의 인기 게시물

느려진 구글 크롬 속도 2배 빨라지는 3가지 설정 방법 (2026년 최신 가이드)

카카오톡 용량 줄이기! 대화방 파일 삭제로 스마트폰 용량 확보법 (1분 해결)

업무 속도 3배 빨라지는 윈도우 기본 캡처 도구 단축키 및 200% 활용 꿀팁