Files
ConfigData/rename-media/oldversion/rnmedia.py
CrazyJasonwell 290ff8984f commit
2026-10-07 11:07:00 +08:00

131 lines
5.0 KiB
Python
Raw 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
import argparse
from datetime import datetime
# ====================== 【配置区,不再写死目录】 ======================
LOG_FILE = "./rename_log.txt"
# 清洗规则
RULES = [
(r"^[A-Za-z] ", ""), #1.移除开头单个字母+空格
(r"\[.*?\]", ""), #2.移除英文方括号及内部内容
(r"【.*?】", ""), #3.移除中文【】及内部内容
(r"丨", ""), #清除汉字竖线 丨
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语|双语字幕)\b", "", re.IGNORECASE),
(r"\.+", ""), #删除连续的点
(r"\s", ""), #删除全部空格
# 保留:汉字、半角英文、数字、半角 () . : + -
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+-]", ""),
]
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm",".flv",".avi",".wmv",".ts",".rmvb",".webm",".mp3",".flac",".aac",".wav",".ogg",".m4a",".wma",".alac",".rm",".iso"}
# ====================================================================
def clean_filename(name: str) -> str:
name_no_ext, ext = os.path.splitext(name)
# 全角转半角
def full2half(s):
result = []
for char in s:
code = ord(char)
if code == 12288:
char = chr(32)
elif 65281 <= code <= 65374:
char = chr(code - 65248)
result.append(char)
return "".join(result)
name_no_ext = full2half(name_no_ext)
for item in RULES:
if len(item) == 3:
pat, repl, flag = item
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
else:
pat, repl = item
name_no_ext = re.sub(pat, repl, name_no_ext)
name_no_ext = name_no_ext.strip()
return name_no_ext + ext
def write_log(msg: str):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
line = f"[{now}] {msg}"
print(line)
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(line + "\n")
f.flush()
def main():
parser = argparse.ArgumentParser(description="媒体文件名批量清洗重命名工具")
parser.add_argument("--dir", required=True, help="目标根目录路径")
parser.add_argument("--apply", action="store_true", help="加上此参数才执行真实重命名;默认仅预览DryRun")
args = parser.parse_args()
target_dir = args.dir
DRY_RUN = not args.apply
# 校验目录是否存在
if not os.path.isdir(target_dir):
print(f"错误:目录不存在 -> {target_dir}")
return
# 每次运行前清空日志文件
with open(LOG_FILE, "w", encoding="utf-8") as f:
f.flush()
write_log("===== 文件名+文件夹清洗(移除开头A 中文片名前缀) =====")
write_log(f"根目录:{target_dir}")
write_log(f"预览模式 DRY_RUN = {DRY_RUN}")
file_rename_list = []
dir_rename_list = []
total_scan_dirs = 0
total_all_files = 0 # 全部扫描到的文件(所有后缀)
total_media_files = 0 # 媒体文件(ALLOW_EXT后缀)
for root, dirs, files in os.walk(target_dir, topdown=False):
total_scan_dirs += 1
for fname in files:
total_all_files +=1
ext = os.path.splitext(fname)[1].lower()
if ext in ALLOW_EXT:
total_media_files += 1
new_name = clean_filename(fname)
if new_name != fname:
old_path = os.path.join(root, fname)
new_path = os.path.join(root, new_name)
file_rename_list.append((old_path, new_path))
write_log(f"待修改文件-> {fname} → {new_name}")
# 处理文件夹
for dname in dirs:
new_name = clean_filename(dname)
if new_name != dname:
old_path = os.path.join(root, dname)
new_path = os.path.join(root, new_name)
dir_rename_list.append((old_path, new_name))
write_log(f"待修改文件夹-> {dname} → {new_name}")
# ========== 执行阶段 ==========
if not DRY_RUN:
# 先文件
for old, new in file_rename_list:
try:
os.rename(old, new)
except Exception as e:
write_log(f"【文件重命名失败】{old} -> {new} | 错误:{e}")
# 后文件夹
for old, new in dir_rename_list:
try:
os.rename(old, new)
except Exception as e:
write_log(f"【文件夹重命名失败】{old} -> {new} | 错误:{e}")
# 最终汇总输出
write_log(f"任务完成,总扫描目录:{total_scan_dirs},待修改文件夹:{len(dir_rename_list)}")
write_log(f"总扫描文件:{total_all_files},媒体文件:{total_media_files},待修改文件:{len(file_rename_list)}")
write_log("============================================================")
if __name__ == "__main__":
main()