如何实现文件移动至Archive子文件夹并在重名时自动递增命名?
文件归档时的同名文件递增重命名方案
我需要把一个或多个文件移动到“archive”子文件夹,但处理同名文件时遇到了问题。目前用的是给文件名加“new_”前缀的方式(比如filename.xlsx→new_filename.xlsx),但这个方式不仅不美观,还没法处理多次同名文件移动的情况——第三次移动同名文件时就会因为new_filename.xlsx已经存在而失败。
当前问题示例
File 1 : src\filename.xlsx ---> src\archive\filename.xlsx (ok) File 2 : src\filename.xlsx ---> src\archive\new_filename.xlsx (ok) File 3 : src\filename.xlsx -x-> (problem)
期望效果
File 1 : src\filename.xlsx ---> src\archive\filename.xlsx File 2 : src\filename.xlsx ---> src\archive\filename_1.xlsx File 3 : src\filename.xlsx ---> src\archive\filename_2.xlsx
现有实现代码
import os import shutil from pathlib import Path src = r'C:\testonsdestrucs' for file in os.listdir(src): full_path = os.path.join(src, file) if not os.path.isdir(full_path): archive = os.path.join(src, 'Archive') Path(archive).mkdir(parents=True, exist_ok=True) files_archive = [] for file_archive in os.listdir(archive): files_archive.append(file_archive) if file in files_archive: os.rename(full_path, os.path.join(archive, 'new_' + file) ) else: shutil.move(full_path, archive )
改进后的解决方案
核心思路是拆分文件名与扩展名,通过递增数字后缀的方式,自动查找第一个未被占用的目标文件名,确保每次移动都能成功。
实现代码
import os import shutil from pathlib import Path src = r'C:\testonsdestrucs' archive_dir = os.path.join(src, 'Archive') # 提前创建归档文件夹,避免循环内重复执行 Path(archive_dir).mkdir(parents=True, exist_ok=True) for file_name in os.listdir(src): full_src_path = os.path.join(src, file_name) # 跳过子文件夹,只处理文件 if os.path.isdir(full_src_path): continue # 拆分文件名主体和扩展名 base_name, ext = os.path.splitext(file_name) target_path = os.path.join(archive_dir, file_name) # 循环查找第一个不存在的目标路径 counter = 1 while os.path.exists(target_path): # 拼接带递增后缀的文件名 target_path = os.path.join(archive_dir, f"{base_name}_{counter}{ext}") counter += 1 # 执行文件移动 shutil.move(full_src_path, target_path)
代码说明
- 提前初始化归档文件夹,减少循环内的重复操作
- 使用
os.path.splitext拆分文件名,方便灵活拼接递增后缀 - 通过
while循环自动检测目标路径是否存在,确保找到唯一可用的文件名 - 统一使用
shutil.move处理文件移动,无需区分重命名和普通移动逻辑,代码更简洁
内容的提问来源于stack exchange,提问作者Tartinette
相关产品推荐
相关产品推荐

