【问题标题】:How to delete older files but keep recent ones during backup?如何在备份期间删除旧文件但保留最近的文件?
【发布时间】:2019-08-02 19:11:11
【问题描述】:

我有一台远程服务器,每天将 30 多个备份文件复制到本地服务器,当且仅当成功复制较新的备份时,我想删除旧备份。

使用我尝试的不同代码,我设法删除了旧文件,但我遇到的问题是,如果它找到一个新备份,它会删除所有旧文件。

我有类似的东西(用 20 个虚拟机想象一下):

vm001-2019-08-01.bck
vm001-2019-07-28.bck
vm002-2019-08-01.bck
vm003-2019-07-29.bck
vm004-2019-08-01.bck
vm004-2019-07-31.bck
vm004-2019-07-30.bck
vm004-2019-07-29.bck
...

我想删除所有内容,只保留最近的内容。 即:擦除:

vm001-2019-07-28.bck
vm002-2019-07-29.bck
vm004-2019-07-31.bck
vm004-2019-07-30.bck
vm004-2019-07-29.bck

并且只保留:

vm001-2019-08-01.bck
vm002-2019-08-01.bck
vm003-2019-07-29.bck
vm004-2019-08-01.bck

我遇到的问题是,如果我最近有任何机器的备份,像 vm-003-2019-07-29 这样的文件会被删除,因为它们比较旧,即使它们来自不同的机器。

我知道网站上有这个问题的几个变体,但我不能完全解决这个问题。

我一直在尝试这段代码的变体:

#!/bin/bash

for i in ./*.bck
do
  echo "found" "$i"
  if [[ -n $(find "$i" -type f -mmin -1440) ]]
  then
    echo "$i"
    find "$i" -type f -mmin +1440 -exec rm -f "$i" {} +
  fi
done

(回显仅用于调试目的)

此时,此代码会找到较新和较旧的文件,但不会删除任何内容。如果我输入find "$i" -type f -mmin +1440 -exec echo "$i" {} +,它永远不会打印任何东西,好像find $i 没有找到任何东西,但是当我在终端中将它作为单独命令运行时,它会打印(减去-exec 部分)。

我已经使用 touch -d 测试了这个脚本生成具有不同时间戳的文件,但我没有成功。

【问题讨论】:

    标签: linux bash backup


    【解决方案1】:

    除非您在文件名之前添加-name 测试,否则find 会认为"$i" 是要搜索的目录的名称。所以您的find 命令应该是:

    find -name "$i" -type f -mmin -1440
    

    将在当前目录中搜索。或者

    find /path/to/dir -name "$i" -type f -mmin -1440
    

    它将在名为“/path/to/dir”的目录中搜索。

    但是,基于BashFAQ/099,我会这样做以删除每个 VM(未经测试)的最新文件以外的所有文件:

    #!/bin/bash
    declare -A newest  # associative array to store name of newest file for each VM
    for f in *
    do
        vm=${f%%-*}    # extracts vm name from filename (i.e. vmm001 from vm001-2019-08-01.bck)
        if [[ -f $f && $f -nt ${newest["$vm"]} ]]
        then
            newest["$vm"]=$f
        fi
    done
    
    for f in *
    do
        vm=${f%%-*}
        if [[ -f $f && $f != ${newest["$vm"]} ]]
        then
            rm "$f"
        fi
    done
    

    设置为针对当前目录中的文件运行。它假定文件的名称如问题所示(VM 名称与文件名的其余部分用连字符分隔)。要使用关联数组,需要 Bash 4 或更高版本。

    【讨论】:

    • 您的第一条评论是正确的。我非常专注于问题的一个方面,我没有看到缺少的参数。我使用了选项 -wholename,因为“$i”指的是绝对路径。我会试试你建议的代码。非常感谢。
    猜你喜欢
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    相关资源
    最近更新 更多