#!/bin/bash
# 配置区(根据实际环境调整)
LOG_ROOT="/path/to/logs"
RETENTION_DAYS=6
DRY_RUN=true
# 时间计算基准(今日零点)
CUTOFF_TS=$(date -d "today 00:00:00" +%s)
CUTOFF_TS=$((CUTOFF_TS - RETENTION_DAYS*86400))
# 颜色输出
COLOR_CLEAN='\033[38;5;245m'
COLOR_DEL='\033[91m'
COLOR_KEEP='\033[92m'
COLOR_END='\033[0m'
find "$LOG_ROOT" -type f -name "*.log" | while read -r FILE; do
DIR_PATH=$(dirname "$FILE")
DIR_NAME=$(basename "$DIR_PATH")
FILE_NAME=$(basename "$FILE")
# 场景1:8位日期目录(YYYYMMDD)
if [[ $DIR_NAME =~ ^[0-9]{8}$ ]]; then
DATE_STR="$DIR_NAME"
# 场景2:6位年月目录(YYYYMM)
elif [[ $DIR_NAME =~ ^[0-9]{6}$ ]]; then
# 解析两种文件名格式:
# 1. XXXXXX-25.log (后缀天数)
# 2. 25.log (纯天数开头)
if [[ $FILE_NAME =~ -([0-9]{2})\.log$ ]]; then
DAY="${BASH_REMATCH[1]}"
elif [[ $FILE_NAME =~ ^([0-9]{2})\.log$ ]]; then
DAY="${BASH_REMATCH[1]}"
else
echo -e "${COLOR_CLEAN}[跳过] 无法解析文件名: $FILE${COLOR_END}"
continue
fi
DATE_STR="${DIR_NAME}${DAY}"
else
echo -e "${COLOR_CLEAN}[跳过] 非常规目录: $DIR_PATH${COLOR_END}"
continue
fi
# 验证日期有效性
if ! DATE_TS=$(date -d "$DATE_STR" +%s 2>/dev/null); then
echo -e "${COLOR_CLEAN}[无效日期] $DATE_STR ➔ $FILE${COLOR_END}"
continue
fi
# 判断是否过期
if [ "$DATE_TS" -lt "$CUTOFF_TS" ]; then
echo -e "${COLOR_DEL}[删除] $(date -d @$DATE_TS +%F) ➔ $FILE${COLOR_END}"
[ "$DRY_RUN" = false ] && rm -f "$FILE"
else
echo -e "${COLOR_KEEP}[保留] $(date -d @$DATE_TS +%F) ➔ $FILE${COLOR_END}"
fi
done
# 清理空目录(真实模式才执行)
if [ "$DRY_RUN" = false ]; then
find "$LOG_ROOT" -type d -empty -delete -print | while read -r DIR; do
echo -e "${COLOR_CLEAN}[清理空目录] $DIR${COLOR_END}"
done
fi
关键说明
-
文件名格式扩展
新增支持两种文件名模式:/202403/event-25.log # 原有带连字符格式 /202403/25.log # 新增纯数字开头格式
-
智能日期提取
# 提取逻辑: - 文件名匹配 XX.log → 直接取前两位作为天数 - 文件名匹配任意内容-XX.log → 取最后两位作为天数
执行示例
# 测试模式输出
[保留] 2024-03-25 ➔ /logs/202403/25.log
[删除] 2024-03-18 ➔ /logs/202403/1740760483-18.log
# 实际删除模式
DRY_RUN=false ./log_cleaner.sh
建议首次使用时保持 DRY_RUN=true
观察处理结果,确认无误后再切换至实际删除模式。
此脚本会匹配删除
202501/01.log
202501/15895471221-01.log
这种格式的日志