Python 批量复制文件并重命名:留底+规范命名一步做
用 Python shutil.copy2 批量复制文件到目标目录同时按规则重命名,保留原文件和修改时间,适合做版本留底、批量转存。
场景痛点
要把一批文件做个留底备份,同时改名成规范格式:比如把「合同扫描件」复制到 2024留底 目录,文件名统一加日期前缀。手动复制粘贴再改名,几百个文件做到崩溃,还容易漏掉原文件的修改时间。用 Python shutil.copy2 复制(会保留修改时间)的同时按新规则命名,原文件不动,留底一份干净命名的副本。
用到的库
纯标准库,无需 pip 安装:
# os、shutil 为标准库
完整代码
import os
import shutil
from datetime import datetime
# ========== 配置区 ==========
SOURCE_DIR = "./原件"
DEST_DIR = "./2024留底"
PREFIX = datetime.now().strftime("%Y%m%d_") # 用今天日期做前缀
DRY_RUN = True
# ============================
def main():
if not os.path.isdir(SOURCE_DIR):
print(f"目录不存在:{SOURCE_DIR}")
return
count = 0
for name in os.listdir(SOURCE_DIR):
src_path = os.path.join(SOURCE_DIR, name)
if not os.path.isfile(src_path):
continue
stem, ext = os.path.splitext(name)
new_name = f"{PREFIX}{stem}{ext}"
dest_path = os.path.join(DEST_DIR, new_name)
# 目标已存在就跳过,避免重复复制
if os.path.exists(dest_path):
print(f"[跳过] 已存在:{new_name}")
continue
print(f"[{'预览' if DRY_RUN else '复制'}] {name} -> {DEST_DIR}/{new_name}")
if not DRY_RUN:
os.makedirs(DEST_DIR, exist_ok=True)
# copy2 比 copy 多保留修改时间等元数据
shutil.copy2(src_path, dest_path)
count += 1
print(f"\n共复制 {count} 个文件(DRY_RUN={DRY_RUN})")
if __name__ == "__main__":
main()
代码讲解
- shutil.copy2 vs shutil.copy:
copy2在复制内容的同时,把文件的修改时间、访问时间等元数据也一并复制过去,留底归档场景比copy更合适。copy只复制内容,时间会变成当前时刻。 - PREFIX 用日期:
datetime.now().strftime("%Y%m%d_")生成20240914_这样的前缀,复制出来的副本自带操作日期,归档时一眼看出是哪天留的底。想改成项目名前缀直接改这一行。 - 目标已存在就跳过:和 rename 场景不同,复制是新增文件,目标已存在说明之前复制过,跳过防止重复占空间。
- 原文件不动:用的是 copy 不是 move,SOURCE_DIR 里的原件保持原样,DEST_DIR 是新生成的留底。
运行结果
终端打印 合同.pdf -> ./2024留底/20240914_合同.pdf。预览确认命名规则对,把 DRY_RUN 改成 False,DEST_DIR 下生成一批带日期前缀的副本,原件原封不动。
注意事项
- copy2 保留时间:如果你的归档系统按修改时间排序,copy2 保留的原时间能让排序结果和原件一致。
- 大文件占空间:复制不是移动,会双倍占磁盘。确认磁盘剩余空间够再批量跑。
- 同名问题:两次跑脚本(比如不同日期)会生成不同前缀的副本,不会冲突;同一天跑第二次会被「已存在」跳过。
- 符号链接:copy2 默认会跟随软链接复制目标文件;不想跟随就用
copyfile加follow_symlinks=False。 - 复制比移动安全:因为原件保留,复制+改名即使搞错规则,原件还在,比直接移动/改名更适合新手。

更新时间:2026-09-14 21:29:16