Python文件重命名:移除指定前缀、重名自动追加序号问题
批量移除文件名前缀并重名自动加序号的代码故障修复
问题场景
现有一批带1. a1.这类前缀的txt文件,文件列表示例如下:
预期重命名效果
移除所有文件名开头的数字. a1.前缀,若目标路径下已存在同名文件,自动为新文件名追加_1、_2格式的递增序号后缀,预期效果如下:
原有错误实现代码
import os import re import shutil import argparse pattern = "a1" path = "/Users/a1/Documents/Files" count = 0 p = ".* "+str(pattern)+".(.+)" for root, dirs, files in os.walk(path): for file in files: m = re.match(p, file) if m is not None: file_new = m.group(1) if not os.path.exists(os.path.join(root,file_new)): os.rename(os.path.join(root, file), os.path.join(root,file_new)) else: count = count + 1 file_new = m.group(1)+"_"+str(count) os.rename(os.path.join(root, file), os.path.join(root,file_new))
运行上述代码后,重命名结果不符合预期,错误输出效果如下:
原有代码核心问题
- 正则匹配规则错误:编写的正则
.* a1.(.+)未锚定文件名开头,且正则中的.属于通配符未做转义,匹配范围过于宽泛,会错误截断合法文件名,无法精准匹配要删除的数字. a1.前缀结构。 - 计数器逻辑错误:使用全局共享的
count变量计数,没有针对每个去前缀后的基础文件名单独计数,会出现序号跳号、错位问题,例如第一个文件重名生成xxx_1后,下一个不同基础名的文件重名会直接从_2开始编号,不符合预期。 - 重名校验逻辑缺失:仅校验了无后缀的基础文件名是否存在,没有校验追加序号后的文件名是否已存在,极端场景下会覆盖已有文件;同时代码存在缩进语法错误,遍历文件的循环没有正确嵌套在
os.walk的循环块内,无法正常运行。
修正后可直接运行的代码
import os import re # 替换为实际文件路径 target_path = "/Users/a1/Documents/Files" # 精准匹配 开头为「数字. a1.」的前缀,转义点号避免通配匹配 prefix_re = re.compile(r"^\d+\. a1\.(.+)$") for root, _, files in os.walk(target_path): for file in files: match_res = prefix_re.match(file) # 不匹配前缀的文件直接跳过 if not match_res: continue # 提取去掉前缀后的基础文件名 base_name = match_res.group(1) original_full_path = os.path.join(root, file) # 基础文件名无冲突直接重命名 target_full_path = os.path.join(root, base_name) if not os.path.exists(target_full_path): os.rename(original_full_path, target_full_path) continue # 存在冲突时从_1开始递增查找可用文件名 num = 1 while True: # 拆分文件名与扩展名,序号追加在扩展名前 name_part, ext_part = os.path.splitext(base_name) new_name = f"{name_part}_{num}{ext_part}" new_full_path = os.path.join(root, new_name) if not os.path.exists(new_full_path): os.rename(original_full_path, new_full_path) break num += 1
代码说明
- 正则使用
^\d+\. a1\.(.+)$锚定文件名开头,转义点号做精确匹配,只会处理带指定前缀的文件,不会误改普通文件。 - 移除全局计数器,每个触发重名冲突的文件都会从1开始逐个探测可用文件名,不会出现跳号问题,也不会覆盖已存在的带序号文件。
- 自动识别文件扩展名,序号会追加在扩展名之前,例如
笔记.txt重名后会生成笔记_1.txt,符合常规命名习惯,若不需要该特性可直接去掉扩展名拆分逻辑,直接拼接序号即可。 - 修正了原有代码的缩进语法错误,移除了未使用的冗余导入项。
内容的提问来源于stack exchange,提问作者MAK
相关产品推荐
相关产品推荐

