# 파일 리네임 안전 절차 > **작성일:** 2026-01-17 > **버전:** 1.0 > **용도:** 챕터 파일 리네임 시 데이터 손실 방지 --- ## 🚨 위험한 방법 (절대 금지!) ### ❌ 순차 리네임 (덮어쓰기 위험!) ```bash # 30-60화를 31-61화로 변경 (1씩 증가) mv ch-030.md ch-031.md # OK mv ch-031.md ch-032.md # ❌ 충돌! ch-031.md를 덮어씀! mv ch-032.md ch-033.md # ❌ 기존 ch-032 손실! ... ``` **문제:** - ch-031.md → ch-032.md로 변경 시 - 기존 ch-032.md가 덮어쓰기됨 - **원본 ch-031, ch-032 내용 모두 손실!** **실제 사례:** ``` 30-60화 리넘버링 시: → ch-031~045 손실 (덮어쓰기) → 복구 불가능 (Git 커밋 전이었다면) ``` --- ## ✅ 안전한 방법 (필수!) ### 방법 1: 2단계 리네임 (권장) **원리:** 1. 모든 파일을 임시 이름으로 변경 (충돌 없음) 2. 임시 이름에서 최종 이름으로 변경 (충돌 없음) **Step 1: 임시 이름으로 변경 (뒤에서부터 역순!)** ```bash # 뒤에서부터 역순으로 (중요!) mv ch-060.md ch-060.tmp mv ch-059.md ch-059.tmp mv ch-058.md ch-058.tmp ... mv ch-031.md ch-031.tmp mv ch-030.md ch-030.tmp ``` **왜 역순인가?** - 앞에서부터 하면 여전히 충돌 가능 - 뒤에서부터 하면 충돌 없음 **Step 2: 최종 이름으로 변경 (앞에서부터 순서대로)** ```bash # 앞에서부터 순서대로 mv ch-030.tmp ch-031.md mv ch-031.tmp ch-032.md mv ch-032.tmp ch-033.md ... mv ch-059.tmp ch-060.md mv ch-060.tmp ch-061.md ``` **결과:** - 모든 파일 안전하게 변경 - 데이터 손실 없음 --- ### 방법 2: 자동화 스크립트 (강력 권장!) **rename-chapters.sh:** ```bash #!/bin/bash # 안전한 챕터 파일 리네임 스크립트 # # 사용법: # ./rename-chapters.sh START END INCREMENT # # 예시: # ./rename-chapters.sh 30 60 1 # → ch-030~060을 ch-031~061로 변경 (1씩 증가) # # ./rename-chapters.sh 35 50 -5 # → ch-035~050을 ch-030~045로 변경 (5씩 감소) set -e # 에러 시 중단 # 인자 확인 if [ $# -ne 3 ]; then echo "사용법: $0 START END INCREMENT" echo "예시: $0 30 60 1" exit 1 fi START=$1 END=$2 INCREMENT=$3 # 폴더 확인 CHAPTERS_DIR="volumes/vol-02/chapters" if [ ! -d "$CHAPTERS_DIR" ]; then echo "❌ 오류: $CHAPTERS_DIR 폴더가 없습니다." exit 1 fi cd "$CHAPTERS_DIR" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "챕터 리네임 시작" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "범위: ch-$START ~ ch-$END" echo "변경: ${INCREMENT:0:1}$INCREMENT" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 백업 (선택) read -p "Git 커밋되어 있습니까? (y/n): " COMMITTED if [ "$COMMITTED" != "y" ]; then echo "⚠️ 먼저 Git 커밋하세요!" exit 1 fi # Step 1: 임시 이름으로 변경 echo "Step 1: 임시 이름으로 변경 중..." echo "" if [ $INCREMENT -gt 0 ]; then # 증가: 뒤에서부터 역순 for i in $(seq $END -1 $START); do OLD="ch-$(printf '%03d' $i).md" TMP="ch-$(printf '%03d' $i).tmp" if [ -f "$OLD" ]; then mv "$OLD" "$TMP" echo " $OLD → $TMP" fi done else # 감소: 앞에서부터 순서대로 for i in $(seq $START $END); do OLD="ch-$(printf '%03d' $i).md" TMP="ch-$(printf '%03d' $i).tmp" if [ -f "$OLD" ]; then mv "$OLD" "$TMP" echo " $OLD → $TMP" fi done fi echo "" echo "Step 2: 최종 이름으로 변경 중..." echo "" # Step 2: 최종 이름으로 변경 if [ $INCREMENT -gt 0 ]; then # 증가: 앞에서부터 순서대로 for i in $(seq $START $END); do TMP="ch-$(printf '%03d' $i).tmp" NEW="ch-$(printf '%03d' $((i + INCREMENT))).md" if [ -f "$TMP" ]; then mv "$TMP" "$NEW" echo " $TMP → $NEW" fi done else # 감소: 뒤에서부터 역순 for i in $(seq $END -1 $START); do TMP="ch-$(printf '%03d' $i).tmp" NEW="ch-$(printf '%03d' $((i + INCREMENT))).md" if [ -f "$TMP" ]; then mv "$TMP" "$NEW" echo " $TMP → $NEW" fi done fi echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "✅ 리네임 완료!" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # 검증 echo "" echo "검증 중..." ./verify-chapters.sh ``` **verify-chapters.sh:** ```bash #!/bin/bash # 챕터 파일 검증 스크립트 CHAPTERS_DIR="volumes/vol-02/chapters" cd "$CHAPTERS_DIR" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "챕터 파일 검증" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 1. .tmp 파일 확인 TMP_COUNT=$(ls *.tmp 2>/dev/null | wc -l) if [ $TMP_COUNT -gt 0 ]; then echo "❌ 임시 파일 발견: $TMP_COUNT개" ls *.tmp exit 1 else echo "✅ 임시 파일 없음" fi # 2. 파일 개수 MD_COUNT=$(ls ch-*.md 2>/dev/null | wc -l) echo "✅ 총 파일: $MD_COUNT개" # 3. 번호 연속성 echo "" echo "파일 목록:" ls ch-*.md | sort -V echo "" echo "번호 연속성 확인..." PREV=-1 ERROR=0 for FILE in $(ls ch-*.md | sort -V); do NUM=$(echo $FILE | grep -oP '\d+') NUM=$((10#$NUM)) # 10진수 변환 if [ $PREV -ne -1 ]; then if [ $NUM -ne $((PREV + 1)) ]; then echo "❌ 번호 누락: ch-$(printf '%03d' $((PREV + 1))).md" ERROR=1 fi fi PREV=$NUM done if [ $ERROR -eq 0 ]; then echo "✅ 번호 연속성 정상" fi # 4. 헤더 형식 확인 echo "" echo "헤더 형식 확인..." grep "^# " ch-*.md | while read LINE; do FILE=$(echo $LINE | cut -d: -f1) HEADER=$(echo $LINE | cut -d: -f2-) # "X권 Y화:" 형식 체크 if ! echo "$HEADER" | grep -qP '^\s*\d+권 \d+화:'; then echo "⚠️ $FILE: 헤더 형식 오류" echo " $HEADER" fi done echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "검증 완료" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" ``` --- ## 📋 리네임 체크리스트 ### 리네임 전 - [ ] **Git 커밋 완료** (가장 중요!) - [ ] 리네임 범위 확인 (START, END) - [ ] 증감 확인 (INCREMENT) - [ ] 다른 파일 수정 중 아님 확인 ### 리네임 실행 - [ ] 스크립트 실행 또는 2단계 수동 리네임 - [ ] Step 1 완료 확인 (.tmp 파일들) - [ ] Step 2 완료 확인 (.md 파일들) ### 리네임 후 검증 - [ ] `.tmp` 파일 없는지 확인 ```bash ls volumes/vol-XX/chapters/*.tmp # 결과 없어야 정상 ``` - [ ] 파일 개수 일치 확인 ```bash # 이전: 60개 ls chapters/ch-*.md | wc -l # 이후: 60개 (또는 +1/-1) ``` - [ ] 번호 연속성 확인 ```bash ls chapters/ch-*.md | sort -V # 빠진 번호 없는지 확인 ``` - [ ] 헤더 내부 화수 일치 확인 ```bash # ch-031.md 파일의 헤더가 "31화"인지 확인 grep "^# " chapters/ch-031.md # 예상: # 2권 31화: 제목 ``` - [ ] Git diff 확인 ```bash git diff --name-status # R로 시작 (Rename) 확인 ``` --- ## 🔧 내부 화수 업데이트 **문제:** - 파일명은 ch-031.md - 내부 헤더는 "# 2권 30화: 제목" ← 불일치! **해결:** ### 자동 업데이트 스크립트 ```bash #!/bin/bash # update-chapter-numbers.sh # 챕터 파일 내부 화수를 파일명과 일치시킴 CHAPTERS_DIR="volumes/vol-02/chapters" cd "$CHAPTERS_DIR" for FILE in ch-*.md; do # 파일명에서 번호 추출 NUM=$(echo $FILE | grep -oP '\d+') NUM=$((10#$NUM)) # 10진수 변환 # 현재 헤더 확인 CURRENT_HEADER=$(head -1 "$FILE") # 새 헤더 생성 (제목 유지) TITLE=$(echo "$CURRENT_HEADER" | sed -E 's/^#\s*\d+권\s*\d+화:\s*//') NEW_HEADER="# 2권 ${NUM}화: $TITLE" # 헤더 교체 sed -i "1s/.*/$NEW_HEADER/" "$FILE" echo "$FILE: $CURRENT_HEADER → $NEW_HEADER" done echo "" echo "✅ 내부 화수 업데이트 완료" ``` --- ## 💡 사용 예시 ### 예시 1: 30-60화를 31-61화로 (1씩 증가) ```bash # Git 커밋 확인 git status # 스크립트 실행 ./rename-chapters.sh 30 60 1 # 검증 ./verify-chapters.sh # 내부 화수 업데이트 ./update-chapter-numbers.sh # Git 커밋 git add . git commit -m "챕터 리네임: 30-60 → 31-61" ``` ### 예시 2: 35-50화를 30-45화로 (5씩 감소) ```bash ./rename-chapters.sh 35 50 -5 ./verify-chapters.sh ./update-chapter-numbers.sh git add . git commit -m "챕터 리네임: 35-50 → 30-45" ``` --- ## 🚨 긴급 복구 ### .tmp 파일이 남아있다면? ```bash # .tmp 파일을 원래 이름으로 복구 for FILE in ch-*.tmp; do ORIGINAL="${FILE%.tmp}.md" mv "$FILE" "$ORIGINAL" echo "복구: $FILE → $ORIGINAL" done ``` ### Git으로 복구 ```bash # 리네임 전 상태로 되돌리기 git reset --hard HEAD # 또는 특정 커밋으로 git reset --hard ``` --- ## 📌 주의사항 1. **반드시 Git 커밋 후 리네임** - 문제 발생 시 복구 가능 2. **스크립트 사용 권장** - 수동 리네임은 실수 위험 높음 3. **검증 필수** - .tmp 파일 확인 - 번호 연속성 확인 - 헤더 일치 확인 4. **내부 화수도 업데이트** - 파일명과 헤더 일치시키기 --- **버전:** 1.0 **최종 수정:** 2026-01-17 **작성자:** Alex + Claude Sonnet 4.5