【问题标题】:Linux shell script to tar.gzip log files older than 1 month grouped by monthLinux shell 脚本到 tar.gzip 日志文件超过 1 个月按月分组
【发布时间】:2015-10-29 03:38:11
【问题描述】:

我有一个充满各种应用程序日志的目录。 示例:

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 的时间戳,但也包含其他数字,如您所见。

我的目标是编写一个可以定期运行一次的脚本来遍历这个目录并执行以下操作: 所有超过 1 个月的日志文件,基于文件名时间戳

  • 对于每个月的文件(30~31 个文件),将它们 tar.gz 压缩到一个文件中
  • 将 tar.gz 文件标记为

App1_201508.tar.gz

日志文件应用程序名称是静态的,时间戳除外。

我想有几种方法可以做到这一点,但我想从 stackoverflow 的伟大思想中收集想法,以找到最简单的方法。

提前致谢

【问题讨论】:

    标签: linux bash shell logging archive


    【解决方案1】:

    这是您更新问题的第三个解决方案:

    #!/usr/bin/env bash
    
    LOGTYPES=$( ls *log* | sed -rn "s/([0-9]{6})[0-9]{2}.*$/\1/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
    # \1 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 脚本不再输出不包含时间戳的文件。

    【讨论】:

    • 如果我想按文件名分隔存档文件,我需要如何处理上述解决方案。像 App1YYYYMM 和 App2YYYYMM。目前它只是抓取基于 YYYYMM 的每个日志文件。
    • 如果你尝试一下,你会发现它就是这样做的。
    • 啊,我想我应该更详细地解释一下日志文件。这是文件名格式的示例。 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正如你可以看到有下划线和。分隔符。
    • 看看我的脚本的第三个版本。
    • 你是万王之王。这就像一个冠军。棒极了。非常感谢。
    【解决方案2】:

    这里,不确定是否工作

    #!/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,... 
    

    以 runwhen 或 cron 为例,每天运行一次脚本

    【讨论】:

    • 实际上,您必须将月份声明为整数变量。否则,$OLDMONTH 将类似于08-1,它将无法正常工作。其次,即使它确实有效,$OLDMONTH 也将类似于7,而不是07,因此它不适合测试。第三,如果你做对了,并且在 1 月份运行了这个脚本,它会将文件与 00 进行比较,而不是应有的 12。
    • 你是对的,你应该循环除此之外的所有文件和月份。您可以使用特定日期运行日期
    • 是的,问题是月份是两位数。我的方法是使用 find /DIR -name "App12015$OLDMONTH*.log | xargs tar rvf App12015$OLDMONTH.tar 但不确定月份问题
    • run date -d YYYYMMDD +"%y%m" 得到一个整数,可以与 test -gt (大于) to date +"%y%m" (now)进行比较
    猜你喜欢
    • 2023-03-26
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    相关资源
    最近更新 更多