DB_JOB/_스크립트/_rename_prefix.py
hehihoho3 df16c98366 백업: DB수집 전체 스냅샷 (공공기관2 정리 전)
공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:15:40 +09:00

102 lines
4.0 KiB
Python

# -*- coding: utf-8 -*-
"""작업파일명 앞에 광역(도) 접두 — {시}.xlsx → {도}_{시}.xlsx (2026-06-01).
1) 광역_사이트맵/{도}/{N.시}/{시}.xlsx 메인 파일 rename (백업·부수파일 제외).
2) 모든 .py(_스크립트/ + 광역_사이트맵/**)에서 리터럴 '{시}.xlsx''{도}_{시}.xlsx' 치환.
(충남·충북 phase234 SITES 하드코딩 경로, 기관폴더 스크립트 등)
※ 동적 빌더(f'{name}.xlsx' 등 5곳)는 별도 수동 수정.
사용: python -X utf8 _rename_prefix.py dry|run
"""
import os, sys, io, re
ROOT = r'D:\01.프로젝트\DB수집'
MAP = os.path.join(ROOT, '작업파일', '광역_사이트맵')
PROVS = ['충청남도', '충청북도', '전북특별자치도', '제주특별자치도']
def build_map():
"""반환 [(도, 폴더명(N.시), 시, 기존xlsx경로, 새xlsx경로)]"""
out = []
for prov in PROVS:
pdir = os.path.join(MAP, prov)
if not os.path.isdir(pdir):
continue
for fold in sorted(os.listdir(pdir)):
fdir = os.path.join(pdir, fold)
if not os.path.isdir(fdir):
continue
si = fold.split('.', 1)[-1] # 'N.시' → 시
old = os.path.join(fdir, f'{si}.xlsx')
if os.path.exists(old):
new = os.path.join(fdir, f'{prov}_{si}.xlsx')
out.append((prov, fold, si, old, new))
return out
def py_files():
fs = []
sdir = os.path.join(ROOT, '_스크립트')
for f in os.listdir(sdir):
if f.endswith('.py'):
fs.append(os.path.join(sdir, f))
for dp, _, names in os.walk(MAP):
for n in names:
if n.endswith('.py'):
fs.append(os.path.join(dp, n))
return fs
def main():
mode = sys.argv[1] if len(sys.argv) > 1 else 'dry'
m = build_map()
# 시→도 (리터럴 치환용). 시명 길이 내림차순(부분일치 방지)
s2p = {si: prov for prov, fold, si, o, n in m}
print(f'== rename 대상 {len(m)}개 ==')
for prov, fold, si, o, n in m:
print(f' {prov}/{fold}/{si}.xlsx → {prov}_{si}.xlsx')
if mode == 'run':
if os.path.exists(n):
print(' !! 이미 존재, 스킵'); continue
os.rename(o, n)
# 리터럴 치환
print('\n== .py 리터럴 치환 ==')
keys = sorted(s2p.keys(), key=len, reverse=True)
total_files = 0; total_hits = 0
for fp in py_files():
try:
txt = io.open(fp, encoding='utf-8').read()
except Exception:
continue
orig = txt; hits = 0
for si in keys:
prov = s2p[si]
pat = si + '.xlsx'
rep = f'{prov}_{si}.xlsx'
# 이미 접두된 경우 중복 방지: {prov}_{si}.xlsx 는 건드리지 않음
# 음수 룩비하인드로 바로 앞이 '_'(도접두 직후)나 한글이면 스킵
def _sub(mo):
start = mo.start()
before = txt[max(0, start - 1):start]
# 직전이 '_' 또는 한글(다른 시명 꼬리)이면 치환 안 함
if before and (before == '_' or '' <= before <= ''):
return mo.group(0)
return rep
new = re.sub(re.escape(pat), _sub, txt)
if new != txt:
hits += new.count(rep) - orig.count(rep)
txt = new
if txt != orig:
total_files += 1
n_changed = sum(txt.count(f'{s2p[si]}_{si}.xlsx') for si in keys) - sum(orig.count(f'{s2p[si]}_{si}.xlsx') for si in keys)
print(f' {os.path.relpath(fp, ROOT)} (+{n_changed})')
total_hits += n_changed
if mode == 'run':
io.open(fp, 'w', encoding='utf-8').write(txt)
print(f'\n치환 파일 {total_files}개, 경로 {total_hits}건 ({mode})')
print('※ 동적 빌더 수동수정 필요: _dedup_all.py xpath, _tab_batch.py xlsx_path, _jeonbuk_phase234_all.py site(), phase1 3개')
if __name__ == '__main__':
main()