Files
CrazyJasonwell 290ff8984f commit
2026-10-07 11:07:00 +08:00

100 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import re
from datetime import datetime
# ====================== 【配置区,请修改】 ======================
MEDIA_FOLDER = "/Volumes/JoyDisk/myMedia/olstrms/电影/未分类/2025" # Mac挂载NAS路径
# MEDIA_FOLDER = "/media/movies" # 飞牛容器内运行用这个
DRY_RUN = True # True=预览,不修改;确认无误改为False执行改名
SKIP_PROCESSED = False # True=跳过已处理(文件名含(20xx)年份)
LOG_FILE = "./rename_log.txt"
# =================================================================
# 清洗正则规则(文件夹、文件共用一套)
RULES = [
(r"^[A-Za-z] ", ""), # 【新增】移除开头单个英文字母+空格:A 流浪地球 → 流浪地球
(r"(?<=[a-zA-Z0-9])\.(?=[a-zA-Z0-9])", " "), # Dune.Part → Dune Part
(r"\[.*?\]", ""), # 删除全部 [xxx] 方括号内容
(r"\s*(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD)\b", ""),
(r"\.+", " "), # 剩下连续多个点替换成空格
]
# 支持的文件后缀
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub"}
def clean_name(name: str) -> str:
"""统一清洗函数,文件夹名、文件名共用"""
name_no_ext, ext = os.path.splitext(name)
# 处理 A . B . C 这种「字母 空格 . 空格 字母」
while re.search(r"(\w) \. (\w)", name_no_ext):
name_no_ext = re.sub(r"(\w) \. (\w)", r"\1\2", name_no_ext)
# 执行所有正则替换规则
for pattern, repl in RULES:
name_no_ext = re.sub(pattern, repl, name_no_ext)
# 合并连续空格,去除首尾空格
name_no_ext = re.sub(r"\s+", " ", name_no_ext).strip()
return name_no_ext + ext
def write_log(msg: str):
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
line = f"[{time_str}] {msg}"
print(line)
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(line + "\n")
if __name__ == "__main__":
write_log("===== 文件名+文件夹清洗(移除开头A 中文片名前缀) =====")
write_log(f"根目录:{MEDIA_FOLDER}")
write_log(f"预览模式 DRY_RUN = {DRY_RUN}")
dir_rename_list = []
file_rename_list = []
# 遍历收集(自底向上,防止目录路径错乱)
for root, dirs, files in os.walk(MEDIA_FOLDER, topdown=False):
# 文件
for fname in files:
ext = os.path.splitext(fname)[1].lower()
if ext not in ALLOW_EXT:
continue
new_name = clean_name(fname)
if new_name != fname:
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
write_log(f"跳过文件(疑似已处理): {fname}")
continue
old_path = os.path.join(root, fname)
new_path = os.path.join(root, new_name)
file_rename_list.append((old_path, new_path))
# 文件夹
for dname in dirs:
new_name = clean_name(dname)
if new_name != dname:
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
write_log(f"跳过文件夹(疑似已处理): {dname}")
continue
old_path = os.path.join(root, dname)
new_path = os.path.join(root, new_name)
dir_rename_list.append((old_path, new_name))
# 先改文件夹,再改文件
dir_count = 0
for old, new in dir_rename_list:
write_log(f"【文件夹】{os.path.basename(old)} → {os.path.basename(new)}")
dir_count +=1
if not DRY_RUN:
os.rename(old, new)
file_count =0
for old, new in file_rename_list:
write_log(f"【文件】{os.path.basename(old)} → {os.path.basename(new)}")
file_count +=1
if not DRY_RUN:
os.rename(old, new)
write_log(f"任务完成,待修改文件夹:{dir_count},待修改文件:{file_count}")
write_log("="*60 + "\n")