Python脚本实现保留设备备份文件的最早实例(含当前月份)
配置备份文件清理脚本解决方案
问题描述
我有一个存储多个配置备份文件的目录,文件命名规则为「备份日期__设备名.tar」。需求是编写Python脚本遍历目录:
- 保留所有旧月份的备份文件
- 仅保留当前月份每个设备的最早备份实例
示例执行前目录内容:
02-10-2023__Device1.tar 03-10-2023__Device2.tar 01-11-2023__Device1.tar 03-11-2023__Device2.tar 04-11-2023__Device1.tar 06-11-2023__Device2.tar 11-11-2023__Device2.tar ...
预期执行后目录内容:
02-10-2023__Device1.tar 03-10-2023__Device2.tar 01-11-2023__Device1.tar 03-11-2023__Device2.tar
当前尝试用os.listdir获取文件,datetime获取当前年月,但卡在统计同设备文件的步骤,现有代码如下:
import os, datetime today=datetime.date.today() month=today.month year=today.year date=str(str(month) + "-" + str(year)) files=os.listdir() erase=[] for file in files: if ????? and str(file[3:10]) == date: erase.append(file) os.remove(erase)
不确定如何添加判断条件筛选待删除文件,尝试files.count(file[3:]) > 1无效,想确认思路是否正确或有无更简便方法。
问题分析与优化方案
你的核心思路没问题,但存在几个关键问题需要修正:
- 删除逻辑错误:
os.remove(erase)传入了列表而非单个文件名,且边遍历目录边删除文件容易引发遍历异常,应该先收集所有待删除文件再统一处理。 - 缺少设备分组逻辑:需要先将当前月份的文件按设备名分组,才能筛选出每个设备需保留的最早备份。
- 日期处理可优化:将文件名中的日期转为
date对象,能更安全准确地进行年月匹配和日期排序。
完整实现代码
import os from datetime import date def parse_backup_file(filename): """解析备份文件名,返回(日期对象, 设备名),不符合规则则返回None""" try: date_part, device_part = filename.split("__") day, month, year = map(int, date_part.split("-")) backup_date = date(year, month, day) device_name = device_part.replace(".tar", "") return backup_date, device_name except (ValueError, IndexError): return None, None # 获取当前年月 today = date.today() current_year, current_month = today.year, today.month # 按设备分组存储当前月份的备份文件,key为设备名,value为(日期, 文件名)列表 current_month_backups = {} to_delete = [] # 遍历目录文件 for filename in os.listdir(): if not filename.endswith(".tar"): continue backup_date, device_name = parse_backup_file(filename) if not backup_date or not device_name: continue # 旧月份文件直接保留,跳过处理 if backup_date.year != current_year or backup_date.month != current_month: continue # 按设备分组存储当前月份的文件 if device_name not in current_month_backups: current_month_backups[device_name] = [] current_month_backups[device_name].append((backup_date, filename)) # 筛选每个设备当前月份需删除的文件(除最早备份外的所有文件) for device_files in current_month_backups.values(): # 按日期排序,最早的备份排在首位 device_files.sort(key=lambda x: x[0]) # 从第二个元素开始加入删除列表 for _, filename in device_files[1:]: to_delete.append(filename) # 执行删除操作 for filename in to_delete: try: os.remove(filename) print(f"已删除: {filename}") except Exception as e: print(f"删除失败 {filename}: {str(e)}")
关键逻辑说明
- 文件名解析:通过
split("__")拆分日期与设备名,将日期字符串转为date对象,避免字符串匹配的误差。 - 设备分组:用字典存储当前月份每个设备的所有备份,方便后续批量处理同设备文件。
- 安全删除:先收集所有待删除文件,再统一执行删除操作,避免遍历目录时修改文件结构引发的异常。
内容的提问来源于stack exchange,提问作者Demions
相关产品推荐
相关产品推荐

