Python提取PX_N.gmspr文件名ID匹配p.X文件夹批量移动文件
gmspr格式文件批量匹配归档实现方案
核心待解决的文件名ID提取问题直接用正则匹配即可,不需要复杂的字符串切割逻辑,匹配规则完全贴合给定命名规范,不会出现错配。
核心ID提取逻辑
针对PX_N.gmspr格式的文件名,使用正则表达式^P(\d+)_[23689AH]\.gmspr$做匹配:
- 固定匹配开头大写P,后面紧跟的连续数字就是要提取的X值,存在第一个捕获组中
- 正则直接限定了下划线后N的合法取值(2/3/6/8/9/A/H),不符合命名规则的脏文件会被直接过滤,不会进入后续匹配流程
- 提取到的X值统一转成整数类型,和文件夹提取的X值类型保持一致,避免字符串和数字比对出现匹配失败的问题
对应提取代码片段:
import re file_pattern = re.compile(r'^P(\d+)_[23689AH]\.gmspr$', re.IGNORECASE) # 示例文件名测试 test_filename = "P24_3.gmspr" match_res = file_pattern.match(test_filename) if match_res: x_id = int(match_res.group(1)) # 提取结果为整数24,可直接和文件夹X值匹配
全量批量移动实现步骤
提前做路径映射字典能大幅提升处理效率,不用每处理一个文件就遍历所有文件夹找对应ID:
- 第一步:遍历所有存放p.X文件夹的父级目录(即First Folder、Second Folder、Third Folder的共同根目录),递归扫描所有子文件夹,识别所有命名符合
p.X规则的文件夹,将X值作为key、文件夹绝对路径作为value存入字典folder_map。提取文件夹X值可以直接用已验证可行的foldername.split(".",1)[1],记得转成int类型。 - 第二步:遍历Unclassified文件夹下的所有文件,对每个.gmspr后缀的文件用上面写好的正则做匹配,匹配失败的非目标文件直接跳过,匹配成功则拿到对应X值,去
folder_map里找对应的目标文件夹路径。 - 第三步:执行文件移动,不建议频繁用
os.chdir切换工作目录,容易引发路径错乱,直接拼接源文件绝对路径和目标文件绝对路径,用shutil.move完成移动即可,移动前可加一层判断,若目标路径下已存在同名文件,可自动加后缀避免覆盖。
完整参考代码:
import os import re import shutil # -------------------------- 这里修改成自己的实际路径 -------------------------- ROOT_PATH = r"你的根目录绝对路径" UNCLASSIFIED_PATH = os.path.join(ROOT_PATH, "Unclassified") # 存放p.X文件夹的所有父目录 FOLDER_ROOTS = [ os.path.join(ROOT_PATH, "First Folder"), os.path.join(ROOT_PATH, "Second Folder"), os.path.join(ROOT_PATH, "Third Folder") ] # ----------------------------------------------------------------------------- # 1. 预扫描所有p.X文件夹,构建ID-路径映射表 folder_map = {} folder_name_pattern = re.compile(r'^p\.(\d+)$') for root in FOLDER_ROOTS: for dirpath, dirnames, _ in os.walk(root): for dirname in dirnames: dir_match = folder_name_pattern.match(dirname) if dir_match: x_id = int(dir_match.group(1)) folder_map[x_id] = os.path.join(dirpath, dirname) # 2. 扫描待分类文件,匹配后移动 file_pattern = re.compile(r'^P(\d+)_[23689AH]\.gmspr$', re.IGNORECASE) processed_count = 0 error_count = 0 for filename in os.listdir(UNCLASSIFIED_PATH): file_match = file_pattern.match(filename) if not file_match: # 不符合命名规则的文件跳过 continue x_id = int(file_match.group(1)) if x_id not in folder_map: error_count +=1 print(f"未找到ID为{x_id}的对应文件夹,跳过文件{filename}") continue source_path = os.path.join(UNCLASSIFIED_PATH, filename) target_path = os.path.join(folder_map[x_id], filename) # 处理同名文件冲突 if os.path.exists(target_path): name, ext = os.path.splitext(filename) dup_idx = 1 while os.path.exists(os.path.join(folder_map[x_id], f"{name}_{dup_idx}{ext}")): dup_idx +=1 target_path = os.path.join(folder_map[x_id], f"{name}_{dup_idx}{ext}") # 执行移动 shutil.move(source_path, target_path) processed_count +=1 print(f"处理完成,共成功移动{processed_count}个文件,匹配失败{error_count}个文件")
运行前注意:
- 先复制10-20个测试文件到单独的测试目录跑通逻辑,确认匹配、移动结果符合预期再全量运行
- 全量运行前务必备份所有原始文件,避免操作失误导致文件丢失
- 如果p.X文件夹不止分布在三个Folder里,直接把对应父目录路径加到
FOLDER_ROOTS列表里即可,代码会自动递归扫描所有子目录
内容的提问来源于stack exchange,提问作者PARCB
相关产品推荐
相关产品推荐

