python 批量改名时,可以先打印源文件和目标文件的对应关系,再用 --apply 执行。下面的示例用同目录硬链接创建目标,目标已存在时会失败,从而避免覆盖。

生成排序后的改名计划
保存为 rename_files.py。示例仅处理本地练习目录里的普通文件,需要文件系统支持硬链接。目录、隐藏文件和符号链接会被跳过。
import argparse
import os
import re
from pathlib import Path
def main():
parser = argparse.ArgumentParser()
parser.add_argument("directory", type=Path)
parser.add_argument("prefix")
parser.add_argument("--apply", action="store_true")
args = parser.parse_args()
if not args.directory.is_dir() or not re.fullmatch(r"[A-Za-z0-9_-]+", args.prefix):
parser.error("需要有效目录,前缀只允许字母、数字、下划线和短横线")
files = sorted(
p for p in args.directory.iterdir()
if not p.name.startswith(".") and not p.is_symlink() and p.is_file()
)
plan = []
for number, source in enumerate(files, 1):
target = source.with_name(f"{args.prefix}_{number:03d}{source.suffix}")
if target == source:
continue
if target.exists() or target.is_symlink():
parser.error(f"目标已存在:{target.name}")
plan.append((source, target))
for source, target in plan:
print(f"{source.name} -> {target.name}")
if args.apply:
apply_plan(plan)
默认只输出计划。执行前检查编号、扩展名和目标名称。
执行时仍由系统拒绝覆盖
把下面代码追加到同一文件。预览后即使有进程抢先创建目标,os.link 也不会覆盖它。示例适用于执行时没有其他程序改动源文件的目录。
def apply_plan(plan):
for source, target in plan:
try:
os.link(source, target, follow_symlinks=False)
except OSError as error:
raise SystemExit(f"未创建 {target.name}:{error}") from error
try:
source.unlink()
except OSError as error:
raise SystemExit(
f"新旧名称均保留,请检查 {source.name} 与 {target.name}:{error}"
) from error
if __name__ == "__main__":
main()

这批操作按文件逐个生效。中途失败时,先查看哪些文件已改名,再决定如何继续。
用临时目录验证预览、冲突和执行
在独立练习目录运行,rename_files.py 放在 demo 外面。
mkdir demo touch demo/a.jpg demo/b.png python3 rename_files.py demo photo touch demo/photo_001.jpg python3 rename_files.py demo photo --apply rm demo/photo_001.jpg python3 rename_files.py demo photo --apply ls demo
第一次只打印计划,第二次因目标冲突停止。最后应得到 photo_001.jpg 和 photo_002.png。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











