我有一个远程服务器,每天将 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 生成具有不同时间戳的文件,但没有成功。
除非您在文件名之前添加-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 或更高版本。