做文件整理时最烦的就是有一堆文件需要改名,而且不是三五个,是几百、几千甚至几万个。手动一个个右键重命名,不仅慢,还容易把编号顺序弄错。Windows 自带的批量重命名只能做到最基础的“加个前缀再加数字”,遇到需要按 Excel 表格映射改名、需要把抓下来的图片按拍摄时间重命名、需要把特定关键词从几十个文件名里删掉的场景,基本就无能为力了。
这次我们直接看 Python 怎么做,核心思路其实很简单:用os.rename或者pathlib.Path.rename遍历目录,把“旧名字 -> 新名字”的规则通过代码表达出来,一次性执行。Python 做批量重命名的优势不是图形界面多华丽,而是规则可以写得很细:按顺序编号、按日期排序、按 Excel 映射、按正则表达式匹配,全部能自动化,几万个文件也能在几秒内跑完。
下面会从零开始,先介绍环境准备,再给一套可复制的通用脚本,接着拆解几个高频场景:加前缀、加序号、按日期重命名、按 Excel 表格重命名,最后再说说实际跑批之前必须做的几个安全准备,以及新手最容易踩的坑。
1. Python 批量重命名核心能力速览
先把结论放在前面,方便你判断用 Python 做这件事值不值:
| 能力项 | 说明 |
|---|---|
| 支持平台 | Windows / macOS / Linux,只要能装 Python 3 就能用 |
| 核心模块 | os、pathlib、shutil,全部是 Python 内置库 |
| 额外依赖 | 基础改名不需要任何第三方库;按 Excel 映射时用pandas或openpyxl |
| 上手难度 | 低,会写 for 循环就能上手 |
| 批量规模 | 几千到几万个文件都可行,速度取决于目录遍历和文件系统响应 |
| 批量能力 | 支持按序号、按时间、按 Excel 数据、按正则表达式批量重命名 |
| 可定制程度 | 高,文件名加前缀、后缀、去空格、去关键词、大小写转换、文件扩展名修改都能做 |
| 安全机制 | 可以写“试运行模式”,只打印结果不真实改名 |
| 适合读者 | 需要处理大量文档、图片、日志、素材文件;需要成批整理文件名的人 |
这里补充一句:如果你只是偶尔改五六个文件,完全没必要用脚本,直接在文件管理器里改就行。真正适合用 Python 的场景是:
- 文件数量过百,手动改名容易疲劳出错。
- 命名规则复杂,例如“日期_序号_项目名”。
- 需要依赖另一个表格来批量改名。
- 需要反复执行同一套命名规范,想把流程固定下来。
- 文件在多个子文件夹里,需要统一处理。
下面直接进入代码实践。
2. 适用场景与使用边界
2.1 适合谁用
第一类是内容从业者。下载的图片素材名称是乱码,需要按“日期_拍摄地点/主题”重新整理,用脚本一次扫完子文件夹即可。第二类是办公文档处理者,很多 ERP 或 OA 导出的文件名为纯数字,需要按 Excel 中的“项目名称”列批量改成可读名称,人工复制粘贴成千上万次不现实,Python 脚本几十秒能跑完。第三类是开发人员和测试人员,需要把日志文件、导出文件按时间批次重命名归档。
2.2 能解决什么问题
核心是解决三类问题:一是命名不统一,例如大小写混用、空格和中文混用、文件后缀缺失;二是名称没有规律,需要从 Excel、数据库、外部清单中获取目标名称;三是需要顺序化,例如按修改时间排序后追加001, 002, 003这样的序号。
2.3 不适合什么场景
Python 批量重命名不适合处理“需要人眼逐张确认后再改”的资产,比如每一张图片都有独立业务含义,不能仅凭文件名规则判断,这种情况应该半自动:先用脚本输出清单,再由人确认,最后执行。另外如果文件名目标名重复率极高,极容易出现互相覆盖,也需要先跑查重逻辑。
2.4 合规与安全提示
批量重命名本身是对自有文件的管理操作,但使用过程中要注意几点:第一,只处理你拥有合法修改权限的文件,不要扫描或修改系统中其他用户、受版权保护或未授权的目录;第二,如果工作涉及他人隐私数据,例如身份证扫描件、合同信息等,建议不要在未授权环境中复制、改名或外发;第三,涉及公司项目文件时,先确认是否有备份策略,不要在未备份的情况下直接执行全量脚本。建议任何脚本都先加入“模拟模式”,确保新名称全部符合预期再正式执行。
3. 环境准备与前置条件
Python 批量重命名的前置条件非常简单,不需要 GPU、不需要大型依赖库,只需要一个正常的 Python 3 环境和文件夹里文件的可读权限。
3.1 安装 Python 3
如果你还没有安装 Python,先到 Python 官方网站下载 3.8 以上版本,安装过程中注意勾选“Add Python to PATH”,否则后面在命令行里使用python命令会提示找不到。Windows 用户如果已经安装 Microsoft Store 版 Python,通常命令行也会自动识别。
在命令行验证安装结果:
python --version如果看到类似Python 3.10.x或Python 3.12.x的输出,就说明环境可用。Linux 和 macOS 用户可能自带 Python 3,但部分 Linux 系统默认python指向 Python 2,需要改用python3命令。
3.2 是否需要安装第三方库
基础文件名批量重命名只需要内置的os和pathlib,零第三方依赖,断网离线也能运行。只有当场景变成“根据 Excel 表格批量重命名对应的文件”时,才需要安装pandas或openpyxl:
pip install pandas openpyxlpandas用于读取 Excel 内容,openpyxl是让 pandas 识别.xlsx格式的底层引擎。如果电脑上已经有 Anaconda,那这两个库大概率已经预装,不需要重复安装。
3.3 准备测试目录
正式跑批之前,强烈建议准备一个测试目录,里面放 5 到 10 个无重要意义的文件,例如test1.txt、test2.txt、photo.png。所有脚本先在测试目录里跑通、确认打印结果没问题,再放到真实目录执行。后面章节的代码也建议按这个流程验证。
3.4 编辑器
任何文本编辑器都可以写 Python,例如 VS Code、PyCharm、Notepad,甚至记事本也能跑。唯一的建议是运行脚本时注意编码,Windows 下如果脚本包含中文注释,需要在文件开头声明 UTF-8,Python 3 默认源码编码就是 UTF-8,但部分 Windows 终端显示中文会乱码,这通常只是控制台显示问题,不影响实际文件改名结果。
后续代码统一用.py文件保存,然后在命令行运行:
python rename_files.py4. 掌握最核心的改名函数
4.1 os.rename 基本用法
Python 批量重命名的核心其实只有一个函数。os.rename(src, dst)负责把源路径src改成目标路径dst,既可以改文件名,也可以同时移动文件位置。一个最简单的例子:
import os # 将 001_old.txt 改名为 001_new.txt os.rename("001_old.txt", "001_new.txt")执行后,当前目录下的001_old.txt就变成了001_new.txt。看到这里你会发现一个问题:这个函数只能一次改一个文件,怎么批量?答案是使用for循环加os.listdir或pathlib.Path.glob。
最简单的遍历当前目录下所有.txt文件并加上前缀的脚本:
from pathlib import Path folder = Path(".") # 当前目录 for file in folder.glob("*.txt"): new_name = file.stem + "_备份" + file.suffix file.rename(file.with_name(new_name))这段代码里的file.stem是文件名去掉后缀的部分,file.suffix是扩展名,file.with_name(...)表示在同目录下生成新文件名。这样做比字符串拼接路径安全,因为pathlib会自动处理分隔符。
4.2 pathlib 还是 os.path
直接说结论:新版代码更推荐pathlib,因为它不用手动拼路径、不用反复做os.path.join,文件对象直接就能参与遍历和重命名。如果你以后把脚本交给同事,Path写法更不容易出 Windows 和 Linux 路径分隔符问题。os.rename也不是不能用,区别主要在写法上:
os.rename("a.txt", "b.txt"),参数是字符串。Path("a.txt").rename("b.txt"),参数可以是字符串,也可是一个 Path 对象。
4.3 先写一个“试运行”版本
批量改名最大的安全问题就是改错。为了提前看到结果而不实际修改任何文件,可以写一个 dry run 模式,把所有旧名字和新名字打印出来:
from pathlib import Path folder = Path("./test_files") dry_run = True # 改 False 才会真正执行 for file in folder.iterdir(): if file.is_file() and file.suffix == ".txt": new_name = "批量测试_" + file.name target = file.with_name(new_name) print(file.name, "->", target.name) if not dry_run: file.rename(target)dry_run = True时只检查改名结果,确认无误后改成False,再跑一次才会真实执行。实际项目中我建议这个开关永远保留,后续所有脚本都可以沿用。
5. 从一批文件开始:给文件统一增加前缀或后缀
最常见的批量重命名需求是给一批文件添加项目代号或前缀。例如公司要求所有交付文档统一为“XX项目_原始文件名”,或者下载的素材需要加日期前缀。
from pathlib import Path def add_prefix(folder_path: str, prefix: str, suffix_filter: str = ".txt", dry_run: bool = True): folder = Path(folder_path) for file in folder.glob(f"*{suffix_filter}"): if file.is_file(): new_name = f"{prefix}{file.name}" target = file.with_name(new_name) print(file.name, "->", target.name) if not dry_run: file.rename(target) if __name__ == "__main__": # 先把 dry_run 保持为 True 看输出,确认没问题再改 False add_prefix("./test_files", prefix="2025项目_", suffix_filter=".txt", dry_run=True)需要提醒的是,glob(f"*{suffix_filter}")这种写法依赖后缀过滤,但如果文件名本身包含其他字符,比如项目总结.docx,你就需要把suffix_filter改成.docx。如果希望匹配所有文件,不考虑扩展名,则直接遍历folder.iterdir()。
去掉指定关键词也是类似操作:
from pathlib import Path def remove_keyword(folder_path: str, keyword: str, dry_run: bool = True): folder = Path(folder_path) for file in folder.iterdir(): if file.is_file() and keyword in file.name: new_name = file.name.replace(keyword, "") target = file.with_name(new_name) print(file.name, "->", target.name) if not dry_run: file.rename(target)这种脚本最简单,也最容易扩展到实际场景,例如删除文件名里的“副本”“(1)”“final_final”等冗余信息。
6. 按特定规则重命名:为文件添加递增序号
当需要将文件变成1、2、3...或001、002、003...的序号格式时,难点常在于按什么顺序编号。默认的iterdir()或listdir()返回顺序不一定能代表你想要的逻辑顺序,例如按创建时间、按修改时间、按名称排序。
6.1 按文件修改时间顺序加序号
将一批照片按时间顺序重命名为001.jpg、002.jpg,是最常见的需求之一。这里的方案是先把文件收集起来,用文件的修改时间(st_mtime)排序,再批量改名:
from pathlib import Path def rename_by_time_with_index(folder_path: str, suffix_filter: str = ".jpg", prefix: str = "IMG_", dry_run: bool = True): folder = Path(folder_path) files = [f for f in folder.glob(f"*{suffix_filter}") if f.is_file()] # 按照修改时间排序,早的排前面 files.sort(key=lambda p: p.stat().st_mtime) for idx, file in enumerate(files, start=1): new_name = f"{prefix}{idx:04d}{file.suffix}" target = file.with_name(new_name) print(file.name, "->", target.name) if not dry_run: file.rename(target)其中idx:04d表示数字占 4 位,不足补零,输出为0001、0002,如果排序后数量超过 9999,就把位数扩成05d。窗口手动重命名只能做到“加 (1)”这种形式,Python 则能指定任意位数的序号格式化。
6.2 按文件名中已有数字重命名
有时候文件名里已经有一个编号字段,例如第2课_课程介绍.mp4、第10课_实战.mp4,你希望统一改成第02课的格式。这种需求用正则表达式处理最合适:
import re from pathlib import Path pattern = re.compile(r"第(\d+)课") def normalize_course_names(folder_path: str, dry_run: bool = True): folder = Path(folder_path) for file in folder.iterdir(): if file.is_file(): match = pattern.search(file.stem) if match: num = int(match.group(1)) fixed = f"第{num:02d}课" new_stem = pattern.sub(fixed, file.stem) target = file.with_name(new_stem + file.suffix) print(file.name, "->", target.name) if not dry_run: file.rename(target)正则的威力在于,它的匹配范围可以非常复杂。如果只是想要把文件名中的空格替换成下划线、把大写改成小写,都可以先写清楚规则,再套用在统一模板上。
7. 按 Excel 表格批量重命名:根据数据表内容改名文件
从热搜词看,“如何根据 Excel 表格批量重命名对应的 Word 文件名称”是很多人实际面对的需求。这类需求通常会有一份 Excel 映射表,里面有两列,一列是旧文件名(或唯一编号),一列是新文件名(或描述信息)。你需要做的就是把文件夹里的文件,按 Excel 里的对应关系逐个改名。
7.1 准备 Excel 映射数据
假设 Excel 文件名为rename_map.xlsx,结构为两列:
| 旧名称 | 新名称 |
|---|---|
| 合同编号001.pdf | 2025年采购合同-张三.pdf |
| 合同编号002.pdf | 2025年采购合同-李四.pdf |
| 合同编号003.pdf | 2025年采购合同-王五.pdf |
实际操作中,如果旧名称列里没有扩展名,而文件夹中的文件名包含.pdf,就需要代码自己判断并拼接。
7.2 用 pandas 读取 Excel
先安装 pandas 和 openpyxl,然后读取文件:
import pandas as pd from pathlib import Path def rename_from_excel(excel_path: str, folder_path: str, old_col: str = "旧名称", new_col: str = "新名称", dry_run: bool = True): df = pd.read_excel(excel_path) folder = Path(folder_path) # 将文件夹内所有文件做成“文件名词根 -> 完整路径”字典 file_map = {} for f in folder.iterdir(): if f.is_file(): file_map[f.stem] = f for _, row in df.iterrows(): old_name = str(row[old_col]).strip() new_name = str(row[new_col]).strip() file_path = file_map.get(old_name) if file_path is None: print("找不到文件:", old_name) continue new_path = file_path.with_name(new_name + file_path.suffix) print(file_path.name, "->", new_path.name) if not dry_run: file_path.rename(new_path)这里的关键点有几个:
- 使用
load_workbook也可以实现同样流程,但pandas处理筛选、去重、空值判断更简单。 - 如果 Excel 中的“旧名称”包含扩展名,比如
合同编号001.pdf,你需要把file_map[f.name] = f哈希所有文件名而不是词根。 - 如果新旧名称列里有空格,建议先
strip(),避免生成“文件名+空格”的情况。 - 找不到对应文件时不要中断整个脚本,先打印警告,最后人为检查缺失项。
执行前建议多验证一次映射关系:
if __name__ == "__main__": rename_from_excel( excel_path="./rename_map.xlsx", folder_path="./pdf_files", old_col="旧名称", new_col="新名称", dry_run=True, )先确认所有输出都符合预期,再设置dry_run=False正式执行。
7.3 如果文件名能直接用业务字段映射
还有一种更常见的情况,Excel 中并不直接存放“旧文件名”,而是保存了“合同编号”“订单号”等业务字段。假设实际文件名就是订单号,即SO20250101.pdf,Excel 第一列是SO20250101,第二列是华东区_客户A_订单确认书。此时脚本不需要修改 7.2 代码逻辑,只需要把old_col指向订单号列即可。因为文件系统里的文件名词根就是订单号,和 Excel 列的业务编号一一对应。
8. 更复杂的批量重命名:子文件夹递归处理与文件移动
如果文件不是集中在同一个目录,而是分散在多个子文件夹中,上面所有folder.iterdir()脚本都只能处理当前层。需要递归遍历时,改用rglob:
from pathlib import Path def rename_all_in_subfolders(root_path: str, old_kw: str, new_kw: str, dry_run: bool = True): root = Path(root_path) for file in root.rglob("*"): if file.is_file() and old_kw in file.name: new_name = file.name.replace(old_kw, new_kw) target = file.with_name(new_name) print(file, "->", target) if not dry_run: file.rename(target)这段代码会把根目录下所有子目录里,文件名中带old_kw的文件全部替换。rglob是递归版glob,它能找到所有层级下的文件,非常适合文件数量大而且目录结构复杂的素材库。
os.rename还可以把文件移动到另一个目录。如果希望把符合条件的文件全部改名后移动到归档目录,可以这样操作:
import shutil from pathlib import Path def rename_and_move(src_folder: str, dst_folder: str, prefix: str, dry_run: bool = True): src = Path(src_folder) dst = Path(dst_folder) dst.mkdir(parents=True, exist_ok=True) for file in src.glob("*.png"): if file.is_file(): new_name = f"{prefix}_{file.name}" target = dst / new_name print(file, "->", target) if not dry_run: shutil.move(str(file), str(target))这个函数适合按批次归档素材,比如把接收到的截图统一移动到archive/2025/目录,并添加来源前缀。
9. 用正则表达式完成复杂替换
9.1 常见需求:清理文件名中的多余内容和非法字符
批量重命名中真正会让你头疼的,是文件名里各种不统一,例如空格、括号、特殊符号、中英文混排、日期格式不一致。正则表达式可以一次性把这些内容识别出来,并按分组替换。
一段常用的“文件名清理器”示例:
import re from pathlib import Path def clean_filename(name: str) -> str: # 去掉文件头尾空格 stem, suffix = Path(name).stem, Path(name).suffix stem = stem.strip() # 多个连续空格替换为单个下划线 stem = re.sub(r"\s+", "_", stem) # 去掉 Windows / Linux 下非法文件名字符 stem = re.sub(r'[\\/:*?"<>|]', "_", stem) # 替换常见的中文和英文括号为圆括号 stem = stem.replace("(", "(").replace(")", ")") return stem + suffix def clean_all_files(folder_path: str, dry_run: bool = True): folder = Path(folder_path) for file in folder.iterdir(): if file.is_file(): new_name = clean_filename(file.name) if new_name != file.name: target = file.with_name(new_name) print(file.name, "->", target.name) if not dry_run: file.rename(target)这段代码可以尽量保证文件名在跨平台使用时不因非法字符报错。你还可以把大写转小写、全角转半角等规则继续扩展进去。
9.2 正则替换思路
对于“把旧关键词换成新关键词”这种需求,使用re.sub比字符串replace更灵活。例如文件名中既有中文括号又有英文括号,括号内内容都不需要,那么:
pattern = re.compile(r"[((].*?[))]") def remove_brackets_content(folder_path: str, dry_run: bool = True): folder = Path(folder_path) for file in folder.iterdir(): if file.is_file(): new_stem = pattern.sub("", file.stem).strip(" _-") target = file.with_name(new_stem + file.suffix) print(file.name, "->", target.name) if not dry_run: file.rename(target)这里使用了非贪婪匹配.*?,保证遇到多个括号时每个括号内容分别被删除。正则表达式的学习成本不高,但只要稍微掌握,批量整理素材的效率就能明显提升。
10. 给批量任务加上安全机制
10.1 先输出清单,再执行修改
无论生成环境里写得多熟练,都应该先打印一份“旧名称 -> 新名称”清单,人工快速扫描有没有明显错误,然后再正式执行。如果脚本输出实在太多,可以把清单保存到 CSV 文件里仔细检查:
import csv from pathlib import Path def export_rename_map(folder_path: str, output_csv: str = "rename_map_preview.csv"): folder = Path(folder_path) rows = [] for idx, file in enumerate(folder.iterdir(), start=1): if file.is_file(): new_name = f"{idx:04d}{file.suffix}" rows.append([file.name, new_name]) with open(output_csv, "w", encoding="utf-8-sig", newline="") as f: writer = csv.writer(f) writer.writerow(["old_name", "new_name"]) writer.writerows(rows) print("预览清单已保存到", output_csv)保存为 CSV 而不是文本,方便用 Excel 快速打开,再人工检查或再次加工。
10.2 防止重名覆盖
文件名批量改名时,一个常见的严重问题是有两个不同文件在改名后得到了相同的名字,如果代码没有检查,后执行的那个文件会覆盖先执行的文件。Python 的rename在 Windows 下如果目标已存在,通常会抛出FileExistsError,在部分 Linux 文件系统下却可能静默覆盖。稳妥做法是增加存在性检查:
import os from pathlib import Path def safe_rename(file: Path, new_name: str): target = file.with_name(new_name) if target.exists(): print("目标已存在,跳过:", target.name) return file.rename(target)在更严格的场景,比如文件数量特别多而且业务上不允许覆盖时,还可以先把全部旧路径和新路径记录下来,执行完成后核对最终文件数是否一致。
10.3 先备份再跑全量
如果文件确实很重要,无法恢复到原先状态,最好先复制一份到备份目录,或者直接先执行“导出完整清单”。对几千个文件的普通办公素材来说,压缩成一个 zip 包放到备份环境里,是成本最低且最安全的兜底方案。
11. 批量重命名时资源占用与性能观察
批量重命名不像运行大模型或视频渲染那样吃显存或 GPU,它属于轻量 I/O 密集任务。真正影响速度的主要是文件系统性能和是否跨目录移动。
11.1 速度评估
同一磁盘目录下改几万个文件名,通常只需几秒到十几秒,速度瓶颈主要在文件系统元数据更新。如果文件在机械硬盘上处理,比固态硬盘慢一些,但仍然属于秒级到分钟级。跨磁盘移动文件时,例如从 C 盘移动到 D 盘,会涉及文件内容复制,此时耗时会明显增加,速度取决于磁盘读写性能和文件大小。
11.2 如何观察脚本是否卡住
处理大批量文件时,可以给脚本加上进度输出,每处理 1000 个文件打印一次:
from pathlib import Path def rename_with_progress(folder_path: str, prefix: str, dry_run: bool = True): folder = Path(folder_path) files = [f for f in folder.iterdir() if f.is_file()] total = len(files) for idx, file in enumerate(files, start=1): new_name = f"{prefix}{idx:05d}{file.suffix}" target = file.with_name(new_name) if not dry_run: file.rename(target) if idx % 1000 == 0 or idx == total: print(f"进度: {idx}/{total}") if __name__ == "__main__": rename_with_progress("./test_files", "导出_", dry_run=True)11.3 减少误操作
不需要把脚本运行在待整理目录里,最好的做法是脚本文件放在其他位置,命令行进入工作目录运行:
cd /path/to/your/files python /path/to/your/rename_script.py这样能避免脚本所在目录也被扫描。
12. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Python 命令提示不是内部或外部命令 | Python 未加入 PATH | 命令行执行where python | 安装时勾选 Add Python to PATH,或手动配置环境变量 |
| 打印中文乱码 | 终端编码是 GBK 或 UTF-8 显示问题 | 检查终端编码设置 | 脚本文件保存为 UTF-8 后输出推荐先测试;Windows 可执行chcp 65001 |
FileNotFoundError或找不到文件 | 路径中使用了错误分隔符或路径不存在 | 打印Path.cwd()和完整目标路径 | 使用pathlib.Path替代手动路径拼接,确认工作目录正确 |
| 文件改名后变成空文件名 | 用户写 new_name 时没有带扩展名 | 检查new_name是否包含file.suffix | 用file.stem和file.suffix拆开拼接 |
PermissionError: [WinError 32] | 文件正被 Word、Excel、图片查看器等程序占用 | 关闭打开该文件的程序后重试 | 必要情况下重启资源管理器 |
| 文件被覆盖或数量变少 | target 路径已存在,被rename覆盖 | 在正式跑批前检查target.exists() | 添加存在性检查,重复时跳过并记录日志 |
| pandas 读取 Excel 报错 | 缺少 openpyxl 引擎 | 查看完整报错信息 | 执行pip install openpyxl |
用glob("*.txt")漏掉了部分文件 | 文件名扩展名不是小写,例如.TXT | 打印所有文件名 | 使用rglob("*")加file.suffix.lower()判断 |
| 运行后一个文件都没变 | dry_run或调试开关仍然为True | 检查脚本中的 dry_run 变量 | 明确改成False再执行,并保留日志 |
| 报错无法替换文件扩展名 | 手动拼接新文件名时把扩展名写错 | 单步打印每个 file.name | 统一用file.with_suffix(".pdf")方法处理 |
13. 最佳实践与使用建议
第一,所有批量重命名脚本都设计成“先预览,后执行”。建议把dry_run参数放到函数入口处,比如dry_run: bool = True,执行时先跑一次,确认输出无问题后再启动正式执行。
第二,文件名规则尽量统一。例如编号前补零位数要根据项目最大文件数调整,如果最多 5 万个文件,位数不能少于 5 位。
第三,日志导出比控制台输出更重要。几万个文件改名时,控制台输出会刷屏,而且事后无法追溯。更好的做法是同时写一个.txt或.csv日志,把每次改名的旧名、新名、处理时间记录到文件里。
第四,不要直接把重要文件运行全量脚本。先复制一个小样本目录测试,例如随机抽取 20 个文件放到test_folder/中验证。
第五,检查数据中的空值。Excel 映射中如果“新名称”列有空值,代码需要跳过,而不是生成空文件名的文件。
if not new_name or pd.isna(new_name): print("跳过空名称:", old_name) continue第六,执行完后验证文件总数和命名格式。可以写一句统计代码:
from pathlib import Path folder = Path("./pdf_files") all_files = [f for f in folder.iterdir() if f.is_file()] print("文件总数:", len(all_files)) print("全部符合前缀:", all(f.name.startswith("2025") for f in all_files))第七,如果脚本要分享给同事或给不懂 Python 的人使用,可以先把代码打包成 exe 文件,这样对方不需要安装 Python 就能运行。关于如何使用 PyInstaller 将 Python 脚本打包成 exe,属于另外一篇主题,这里先不做展开。
14. 总结与下一步建议
如果当下的需求就是“给几百个文件加前缀、加序号、按 Excel 改名”,直接照着文章里的pathlib脚本改写即可,第一轮全部使用dry_run=True预览结果,看到新名称符合预期后,再改成False正式执行。从实际经验看,最容易踩的坑不是代码逻辑,而是忘记加存在性检查和dry_run开关,导致误覆盖。
下一步如果想把自动化做得更完整,可以从这几个方向继续深入:
- 学会使用
pathlib.Path.rglob完成子目录递归处理。 - 学会用正则表达式处理各种不规则文件名,例如把日期、学号、项目编号从长文件名中提取出来。
- 学会用 pandas 读取 Excel,把改名规则从“手工映射”升级为“数据表驱动”。
- 学会把已经验证过的脚本打包成可执行文件,交给非技术同事使用。
- 将批量重命名和文档归类逻辑结合,让脚本同时完成改名、分目录、生成索引清单的工作。
几万个文件手动改名不但耗时,而且很容易排序错误。用 Python 脚本处理这种重复机械任务,最大的价值不是省去那十几分钟操作时间,而是让命名标准稳定可控:每次改名的结果都符合同一套规则,日志留存,出错也能追溯。建议先收藏文中基础模板,下次遇到需要批量重命名的素材时,直接拿一份测试目录跑起来。