求助:基于文件名日期的Bash备份清理脚本开发与修复
备份文件清理脚本修复方案
需求说明
- 清理旧备份文件,仅保留3周内的备份:最近7天的每日备份 + 最近3周的每周备份(由周日的每日备份转换而来)
- 优先依据文件名中的日期信息判断保留/删除,不依赖文件实际创建时间
- 文件名格式:
- 每日备份:
Backup_YYYY-MM-DD.bak - 每周备份:
Backup_KWXX.bak(XX为周数)
- 每日备份:
原脚本问题分析
原脚本存在多处语法和逻辑错误,导致无法正常运行:
- 日期提取逻辑错误:尝试执行备份文件来获取文件名,应该用
echo输出文件名后切割 - Bash条件判断语法错误:未使用
[ ]或(( ))包裹条件,直接写表达式不符合Bash语法 - 变量引用缺失:调用
date命令时未引用变量,导致无法解析日期 - 命令拼接错误:重命名文件时未将周数命令的结果嵌入文件名
- 拼写错误:
cut误写为cud,Bash的elif误写为Python的elseif - 日期比较逻辑错误:直接使用
<比较字符串未放在条件判断结构中 - 未处理每周备份的文件名:提取日期时未区分每日/每周备份格式,导致解析失败
- 注释位置错误:删除命令的注释写法错误,导致实际未执行删除逻辑
修复后的脚本
#!/bin/bash # 定义时间阈值:最近7天的起始日期(YYYY-MM-DD格式) daily_threshold=$(date +%F -d "-7 days") # 定义每周备份的阈值:3周前的周数(数字格式) weekly_threshold=$(date +%U -d "-3 weeks") # 遍历所有备份文件 for filename in ./testfiles/*.bak; do # 提取文件名中的核心标识(日期或周数部分) file_identifier=$(echo "$filename" | cut -d "_" -f2 | cut -d "." -f1) # 区分每日备份和每周备份 if [[ "$file_identifier" == [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]; then # 处理每日备份:格式为YYYY-MM-DD this_date="$file_identifier" # 判断是否为周日(%u返回1=周一,7=周日) if [ $(date -d "$this_date" +%u) -eq 7 ]; then # 转换为每周备份:Backup_KWXX.bak(XX为周数) week_num=$(date -d "$this_date" +%U) new_filename="./testfiles/Backup_KW${week_num}.bak" # 避免重复命名,仅当目标文件不存在时重命名 if [ ! -f "$new_filename" ]; then mv "$filename" "$new_filename" fi else # 判断每日备份是否早于7天前,是则删除 if [[ "$this_date" < "$daily_threshold" ]]; then echo "删除旧每日备份:$filename" # rm "$filename" # 测试时注释,确认无误后取消注释 fi fi elif [[ "$file_identifier" == KW[0-9]* ]]; then # 处理每周备份:格式为KWXX week_num=$(echo "$file_identifier" | cut -d "W" -f2) # 判断周数是否早于3周前,是则删除 if (( week_num < weekly_threshold )); then echo "删除旧每周备份:$filename" # rm "$filename" # 测试时注释,确认无误后取消注释 fi else # 处理不符合格式的文件,跳过或提示 echo "忽略非标准格式备份:$filename" fi done
脚本关键说明
- 时间阈值预计算:提前算出7天前的日期和3周前的周数,避免循环中重复计算
- 文件名格式区分:用通配符匹配区分每日/每周备份,未使用正则表达式
- 安全重命名:重命名每周备份时先检查目标文件是否存在,避免覆盖
- 测试模式:删除命令默认注释,先通过
echo确认要删除的文件,无误后再取消注释执行实际删除 - 变量引用规范:所有变量和文件名都用双引号包裹,避免空格或特殊字符导致的错误
- 条件判断规范:使用
[ ]进行字符串/数值比较,(( ))进行数值运算比较,符合Bash语法要求
内容的提问来源于stack exchange,提问作者Haui
相关产品推荐
相关产品推荐

