如何归档符合特定命名规则的.log与.pdf文件(Linux Shell脚本)
嘿,作为自学Shell的新手碰到这些问题太正常啦!我帮你梳理出一套靠谱的解决方案,一步步来搞定它~
解决方案:Shell脚本实现非当日日志/PDF归档压缩
核心思路
先精准筛选出文件名不含当日日期的.log和.pdf文件,将它们统一移动到专属归档目录,再对这个目录进行压缩——这种方式比用tar --exclude更直观可靠,还能避免误包含非目标文件的问题。
完整脚本实现
#!/bin/bash # 定义所有绝对路径(避免crontab环境PATH缺失导致命令找不到) LOG_DIR="/home/tech/logs" PDF_DIR="${LOG_DIR}/pdf" # 创建当日归档目录(格式:/home/tech/logs/archive/20240520) ARCHIVE_DIR="${LOG_DIR}/archive/$(/bin/date +%Y%m%d)" # 定义当日日期(YYYYMMDD格式) CURRENT_DATE=$(/bin/date +%Y%m%d) # 先创建归档目录(如果不存在) /bin/mkdir -p "${ARCHIVE_DIR}" # 移动logs目录下的非当日.log文件 /bin/find "${LOG_DIR}" -maxdepth 1 -type f \ \( -name "*.log" ! -name "*${CURRENT_DATE}*.log" \) \ -exec /bin/mv {} "${ARCHIVE_DIR}/" \; # 移动pdf目录下的非当日.pdf文件 /bin/find "${PDF_DIR}" -maxdepth 1 -type f \ \( -name "*.pdf" ! -name "*${CURRENT_DATE}*.pdf" \) \ -exec /bin/mv {} "${ARCHIVE_DIR}/" \; # 压缩归档目录,生成tar.gz包(压缩后路径更整洁) /bin/tar -czf "${ARCHIVE_DIR}.tar.gz" -C "${LOG_DIR}/archive" "$(/bin/date +%Y%m%d)" # 可选:压缩完成后删除原归档目录(如果不需要保留单独的归档文件) # /bin/rm -rf "${ARCHIVE_DIR}" echo "归档完成:${ARCHIVE_DIR}.tar.gz"
关键细节解释
- 绝对路径的使用:crontab的默认PATH非常有限,所以所有命令(
date/find/mv/tar等)都用绝对路径,避免出现“命令找不到”的错误。 - 解决
$CURRENT_DATE匹配问题:用"*${CURRENT_DATE}*.log"这种双引号包裹变量的方式,确保shell把变量当作完整字符串处理,而不是拆分成单个字符匹配。 - 精准筛选文件:
find命令的条件\( -name "*.log" ! -name "*${CURRENT_DATE}*.log" \)表示:只匹配.log文件,同时排除文件名中包含当日日期的文件,完全贴合你的命名规则。 -maxdepth 1参数:只处理当前目录下的文件,不会递归子目录(如果你的日志目录有子目录,可以根据需求去掉这个参数)。
Crontab配置(让脚本自动执行)
- 先给脚本添加执行权限:
chmod +x /home/tech/scripts/archive_logs.sh
- 编辑crontab任务:
crontab -e
- 添加一行(比如每天凌晨2点执行):
0 2 * * * /bin/bash /home/tech/scripts/archive_logs.sh >> /home/tech/scripts/archive_cron.log 2>&1
0 2 * * *:代表每天凌晨2点触发任务>> ... 2>&1:把脚本的输出和错误都记录到日志文件,方便后续排查问题
测试小技巧
在正式执行移动操作前,可以把-exec /bin/mv {} "${ARCHIVE_DIR}/" \;改成-print,先查看find命令匹配的文件是否正确,确认无误后再替换回mv。
内容的提问来源于stack exchange,提问作者Alyss Flynn
相关产品推荐
相关产品推荐

