Linux shell 脚本 tar.gzip 记录超过 1 个月的按月分组的文件
Linux shell script to tar.gzip log files older than 1 month grouped by month
我有一个充满各种应用程序日志的目录。
示例:
FailedAudit_20150101_000000.log FailedAudit_20150209_000000.log
FailedAudit_20150316_000000.log stats20150116.log stats20150224.log
FailedAudit_20150102_000000.log FailedAudit_20150210_000000.log
FailedAudit_20150317_000000.log stats20150117.log stats20150225.log
FailedAudit_20150103_000000.log RepoV4Error20150227.log
所有日志都有 YYYYMMDD 格式的时间戳,但也有其他数字,如您所见。
我的objective是写一个脚本,可以运行周期性的遍历这个目录,执行以下操作:
对于超过 1 个月的所有日志文件,基于文件名时间戳
- 每个月的文件(30~31 个文件),tar.gz 合并为一个文件
- 将 tar.gz 文件标记为
App1_201508.tar.gz <-- contains all 30 log files
So format AppnameYYYYMM.tar.gz
除时间戳外,日志文件应用程序名称是静态的。
我想有几种方法可以做到这一点,但我想从 Whosebug 的伟大思想中收集想法以找到最简单的方法。
提前致谢
这里,不知道是否有效
#!/bin/bash
MONTH=$(date +%m)
OLDMONTH=$MONTH-1
for FILE in `ls $DIR`
do
if [ ${FILE:-4:2} == $OLDMONTH]; then
# do what you want with the file, it's one month old, eg add it to a list
fi
done
# do what you want with the list, eg tar,...
运行 脚本每天一次,例如 运行when 或 cron
这是您更新后的问题的第三个解决方案:
#!/usr/bin/env bash
LOGTYPES=$( ls *log* | sed -rn "s/([0-9]{6})[0-9]{2}.*$//p" | sort -u )
# the sed command, item by item:
#
# s/ search and replace
# ([0-9]{6}) block of 6 digits, and store it
# [0-9]{2} followed by 2 more digits
# .*$ followed by any and all characters until the end of the input
# / replace all of that with
# the first stored block (the 6 digits)
# /p print the output
#
# So this turns FailedAudit_20150101_000000.log into FailedAudit_201501
THIS_MONTH=$(date +%Y%m)
for LOG in $LOGTYPES; do
MONTH=${LOG: -6} # Last 6 characters of the LOGTYPE are YYYYMM
if [[ "$MONTH" -lt "$THIS_MONTH" ]]; then
LOG_FILES=$(ls ${LOG}*)
tar -czf ${LOG}.tar.gz ${LOG_FILES}
RC=$? # Check whether an error occured
if [[ "$RC" == "0" ]]; then
rm ${LOG_FILES}
fi
fi
done
注意:这假定第一个 8 位数字块是日期戳,之后的所有内容都与要转到的存档无关。
更新:
sed
脚本不再输出不包含时间戳的文件。
我有一个充满各种应用程序日志的目录。 示例:
FailedAudit_20150101_000000.log FailedAudit_20150209_000000.log FailedAudit_20150316_000000.log stats20150116.log stats20150224.log FailedAudit_20150102_000000.log FailedAudit_20150210_000000.log FailedAudit_20150317_000000.log stats20150117.log stats20150225.log FailedAudit_20150103_000000.log RepoV4Error20150227.log
所有日志都有 YYYYMMDD 格式的时间戳,但也有其他数字,如您所见。
我的objective是写一个脚本,可以运行周期性的遍历这个目录,执行以下操作: 对于超过 1 个月的所有日志文件,基于文件名时间戳
- 每个月的文件(30~31 个文件),tar.gz 合并为一个文件
- 将 tar.gz 文件标记为
App1_201508.tar.gz <-- contains all 30 log files So format AppnameYYYYMM.tar.gz
除时间戳外,日志文件应用程序名称是静态的。
我想有几种方法可以做到这一点,但我想从 Whosebug 的伟大思想中收集想法以找到最简单的方法。
提前致谢
这里,不知道是否有效
#!/bin/bash
MONTH=$(date +%m)
OLDMONTH=$MONTH-1
for FILE in `ls $DIR`
do
if [ ${FILE:-4:2} == $OLDMONTH]; then
# do what you want with the file, it's one month old, eg add it to a list
fi
done
# do what you want with the list, eg tar,...
运行 脚本每天一次,例如 运行when 或 cron
这是您更新后的问题的第三个解决方案:
#!/usr/bin/env bash
LOGTYPES=$( ls *log* | sed -rn "s/([0-9]{6})[0-9]{2}.*$//p" | sort -u )
# the sed command, item by item:
#
# s/ search and replace
# ([0-9]{6}) block of 6 digits, and store it
# [0-9]{2} followed by 2 more digits
# .*$ followed by any and all characters until the end of the input
# / replace all of that with
# the first stored block (the 6 digits)
# /p print the output
#
# So this turns FailedAudit_20150101_000000.log into FailedAudit_201501
THIS_MONTH=$(date +%Y%m)
for LOG in $LOGTYPES; do
MONTH=${LOG: -6} # Last 6 characters of the LOGTYPE are YYYYMM
if [[ "$MONTH" -lt "$THIS_MONTH" ]]; then
LOG_FILES=$(ls ${LOG}*)
tar -czf ${LOG}.tar.gz ${LOG_FILES}
RC=$? # Check whether an error occured
if [[ "$RC" == "0" ]]; then
rm ${LOG_FILES}
fi
fi
done
注意:这假定第一个 8 位数字块是日期戳,之后的所有内容都与要转到的存档无关。
更新:
sed
脚本不再输出不包含时间戳的文件。