首页 > 解决方案 > 用于删除以前备份的 bash 脚本

问题描述

我设置了一个每日 cron 作业来备份我的服务器。

在我的文件夹备份中,备份命令会生成 2 个文件:存档本身 .tar.gz 和一个文件 .info.json,如下所示:

-rw-r--r-- 1 root root     1617 Feb  2 16:17 20200202-161647.info.json
-rw-r--r-- 1 root root 48699726 Feb  2 16:17 20200202-161647.tar.gz
-rw-r--r-- 1 root root     1617 Feb  3 06:25 20200203-062501.info.json
-rw-r--r-- 1 root root 48737781 Feb  3 06:25 20200203-062501.tar.gz
-rw-r--r-- 1 root root     1618 Feb  4 06:25 20200204-062501.info.json
-rw-r--r-- 1 root root 48939569 Feb  4 06:25 20200204-062501.tar.gz

如何编写一个仅保留最后 2 个存档并删除所有其他备份(targ.gz 和 info.json)的 bash 脚本。

在此示例中,这意味着删除 20200204-062501.info.json 和 20200204-062501.tar.gz 。

编辑:

我在脚本中将 -name 替换为 -wholename ,但是当我运行它时,它显然没有任何影响。旧档案仍然存在,并且没有被删除。

剧本 :

#!/bin/bash

DEBUG="";
DEBUG="echo DEBUG...";    #put last to safely debug without deleting files
keep=2;
for suffix in /home/archives .json .tar; do
    list=( $( find . -wholename "*$suffix" ) ); #allow for zero names
    if [ ${#list[@]} -gt $keep ]; then
        # delete all but last $keep oldest files
        ${DEBUG}rm -f "$( ls -tr "${list[@]}" | head -n-$keep )";
    fi
done

编辑2:

如果我运行@sorin 脚本,如果我相信脚本输出,它实际上会删除所有内容吗?

运行脚本之前的存档文件夹:

https://pastebin.com/7WtwVHCK

我运行的脚本:

find home/archives/ \( -name '*.json' -o -name '*.tar.gz' \) -print0 |\
    sort -zr |\
    sed -z '3,$p' | \
    xargs -0 echo rm -f

脚本输出:

https://pastebin.com/zd7a2zcq

编辑 3:

该命令 find /home/archives/ -daystart \( -name '*.json' -o -name '*.tar.gz' \) -mtime +1 -exec echo rm -f {} +有效并完成了工作。

标记为已解决

标签: bashshell

解决方案


如果文件是每天生成的,一个简单的方法是利用 -mtime 查找条件:

find /home/archives/ -daystart \( -name '*.json' -o -name '*.tar.gz' \) -mtime +1 -exec echo rm -f {} +
  • -daystart- 使用一天的开始来比较修改时间
  • \( -name '*.json' -o -name '*.tar.gz' \)*.json- 选择以或结尾的文件*.tar.gz
  • -mtime +1- 修改时间超过 24 小时(从当天开始)
  • -exec echo rm -f {} +- 删除文件(删除echo后测试并验证结果是你想要的)

一个更简单的解决方案,避免ls 和它的陷阱,而不是依赖于文件的修改时间:

find /home/archives/ \( -name '*.json' -o -name '*.tar.gz' \) -print0 |\
    sort -zr |\
    sed -nz '3,$p' | \
    xargs -0 echo rm -f
  • \( -name '*.json' -o -name '*.tar.gz' \)*.json- 查找以或结尾的文件tar.gz
  • -print0- 打印它们以空分隔
  • sort -zr--z告诉sort使用 null 作为行分隔符,-r将它们反向排序
  • sed -nz '3,$p'--z同上。'3,$p'- 打印第 3 行和结尾之间的行 ( $)
  • xargs -0 echo rm -f- 使用管道参数执行 rm(测试后删除回显并且您对命令感到满意)

注意:不是所有sort的都sed支持,-z但大多数都支持。如果您遇到这种情况,您可能必须使用更高级别的语言


推荐阅读