删除超过 15 天的文件(月度和年度版本除外)

删除超过 15 天的文件(月度和年度版本除外)

我使用一个简单的查找脚本来删除超过 30 天的备份 tar 文件,但为了保存历史并能够进一步回顾,我想切换到保留最近 15 天以及创建的所有备份每个月的第一天(12 个月)和每年的第一天(回溯 12 年)。完成此任务最优雅的方法是什么?

答案1

如果您的文件具有正确的文件系统级时间戳日期包含在文件名中(例如backup-20230713.tar.gz左右),然后是这样的:

# delete files older than 30 days, except ones from the first of each month
find . -name 'backup-*.tar.gz' -mtime +30 ! -name '*-??????01.tar.gz' -delete

# delete files older than a year, except ones from January 1st
find . -name 'backup-*.tar.gz' -mtime +366 ! -name '*-????0101.tar.gz' -delete

# delete everything older than 12 years:
find . -name 'backup-*.tar.gz' -mtime +$(( 12 * 366 )) -delete

或者,只需在创建文件时根据“组”将文件放置在单独的目录中,例如,每年的第一天位于yearly/,类似地monthly/,其余的位于daily/。然后只需执行以下操作:

find daily/   -mtime +30 -delete
find monthly/ -mtime +366 -delete
find yearly/  -mtime +$((12 * 366)) -delete

在使用之前,您可能应该广泛测试类似的东西。 (使用等创建测试文件touch -d并尝试find不带等的命令-delete

答案2

免责声明:我是该书的当前作者生皮(右旋)此答案中使用的程序(位于https://github.com/raforg/rawhide)。

右旋(和寻找) 可以将修改时间与可以使用 精确指定修改时间的参考文件进行比较touch -t YYYYMMDDhhmm

下面是一个 shell 脚本,它 chdirs 到备份目录,并为过去 12 个月的每个月的第一天和过去 12 年的每年的一月的第一天创建带时间戳的参考文件。

然后它调用右旋列出文件(使用右旋-l选项)需要根据您的规范删除。

它有一个-D选项可以删除文件(使用右旋-UUU选项)。

搜索条件首先定义一个辅助函数,当文件在给定日期(即给定时间和一天后之间)最后一次修改时,该函数返回 true:

on(givenday) { mtime >= givenday && mtime < givenday + day }

然后,搜索条件将匹配常规文件 ( f),这些文件是 tar 文件 ( "*.tar*") 并且至少存在 15 天 ( old(15*days)),并且上次修改日期不是过去十二个月中任何一个月的第一天,或者是第一个月过去十二年中任何一年的一月(例如,!on("1st00".mtime) && ...)。

然后它会删除带时间戳的参考文件。

#!/bin/sh

# Delete backup tarfiles that are older than 15 days except those created
# on the 1st of the month for the past 12 months, and those created on the
# first of January for the past 12 years.

# usage: $0 [-D]
# The -D option deletes files. Without it, they are listed.

# Set this to the path to the backups
path=/path/to/backups

opts=-l
case "$1" in
    -D)
        opts="-UUU"
        ;;
    ?*)
        echo usage: $0 [-D]
        echo "The -D option deletes files (with exceptions)."
        echo "Without it, they will be listed instead."
        echo Files in $path will be listed or deleted.
        exit 1
        ;;
esac

cd "$path" || exit 1

# Create timstamped reference files for the 1st Jan (past 12 years)

year=`date +%Y`
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12
do
    y=`expr $year - $i`
    touch -t ${y}01010000 1stJan`printf %02d $i`
done

# Create timstamped reference files for the 1st of the month (past 12 months)

month=`date +%m`
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12
do
    touch -t $year${month}010000 1st`printf %02d $i`
    if [ $month = 01 ]
    then
        month=12
        year=`expr $year - 1`
    else
        month=`expr $month - 1`
        month=`printf '%02d' $month`
    fi
done

# Delete the backup tarfiles

rh $opts '

    # Define a helper function to make the rest easier to read.
    # True when mtime is on the given day.
    on(givenday) { mtime >= givenday && mtime < givenday + day }

    # Tar files at least 15 days old
    f && "*.tar*" && old(15*days) &&

    # Not last modified on the 1st of the past 12 months
    !on("1st00".mtime) &&
    !on("1st01".mtime) &&
    !on("1st02".mtime) &&
    !on("1st03".mtime) &&
    !on("1st04".mtime) &&
    !on("1st05".mtime) &&
    !on("1st06".mtime) &&
    !on("1st07".mtime) &&
    !on("1st08".mtime) &&
    !on("1st09".mtime) &&
    !on("1st10".mtime) &&
    !on("1st11".mtime) &&
    !on("1st12".mtime) &&

    # Not last modified on the 1st of January for the past 12 years
    !on("1stJan00".mtime) &&
    !on("1stJan01".mtime) &&
    !on("1stJan02".mtime) &&
    !on("1stJan03".mtime) &&
    !on("1stJan04".mtime) &&
    !on("1stJan05".mtime) &&
    !on("1stJan06".mtime) &&
    !on("1stJan07".mtime) &&
    !on("1stJan08".mtime) &&
    !on("1stJan09".mtime) &&
    !on("1stJan10".mtime) &&
    !on("1stJan11".mtime) &&
    !on("1stJan12".mtime)

'

# Clean up the timestamped reference files

rm 1st[01][0-9] 1stJan[01][0-9]

它被硬编码到单个备份目录,但在命令行上使用一个目录很容易。不过,这样做可能很危险。出去要小心。

同样的事情可以在寻找方式大致相同,只是语法不同,语法更多,带时间戳的参考文件数量是两倍。

相关内容