我在/home/backup/
中有一个存储年度备份的目录。在备份文件夹中,我们有以下目录:
/home/backup/2012
/home/backup/2013
/home/backup/2014
/home/backup/2015
/home/backup/2016
/home/backup/2017
每年我都要清理数据,只保留最后三年的备份。
在上述情况下,我必须删除:
/home/backup/2012
/home/backup/2013
/home/backup/2014
找到要删除的目录的最佳方法是什么?我有这个,但它不起作用:
find /home/ecentrix/recording/ -maxdepth 1 -mindepth 1 -type d -ctime +1095 -exec rm -rf {} \;
你们有另一个想法吗?
答案 0 :(得分:8)
由于您的目录有明确定义的整数名称,我只是使用bash来计算适当的目标:
mkdir -p backup/201{2..7} # just for testing
cd backup
rm -fr $(seq 2012 $(( $(date +"%Y") - 3)))
seq
生成一个从2012年到当前年份减3的数字列表,然后传递给rm
进行爆破。
答案 1 :(得分:4)
# Check if extended globbing is on
shopt extglob
# If extended globbing is off, run this line
shopt -s extglob
# Remove all files except 2015, 2016, and 2017
rm -r -i /home/backup/!(2015|2016|2017)
# Turn off extended globbing (optional)
shop -u extglob
shopt -s extglob
可让您匹配除!(...)
内的文件以外的任何文件。因此,该行意味着删除/home/backup
除2015
,2016
或2017
以外的所有文件。
-i
中的rm -r -i ...
标记允许您以交互方式确认删除每个文件。如果您希望自动删除文件,请删除-i
。
此解决方案适用于自动化(例如cron作业)
# Number of latest years to keep
LATEST_YEARS=3
# Get the current year
current_year=$(date '+%Y')
# Get the first/earliest year to keep
first_year=$(( current_year - $(($LATEST_YEARS - 1)) ))
# Turn on extended globbing
shopt -s extglob
# Store years to keep in an array
keep_years=( $(seq $first_year $current_year) )
# Specify files to keep
rm -r /home/backup/!(${keep_years[0]}|${keep_years[1]}|${keep_years[2]})
注意:备份目录中的所有文件将被删除,除了最近3年
答案 2 :(得分:4)
更通用的解决方案
我认为最好按降序遍历目录,然后删除第三个目录之后的目录。这样,当脚本一次又一次地运行时,没有丢失目录的危险:
#!/bin/bash
backups_to_keep=3
count=0
cd /home/backup
while read -d '' -r dir; do
[[ -d "$dir" ]] || continue # skip if not directory
((++count <= backups_to_keep)) && continue # skip if we are within retaining territory
echo "Removing old backup directory '$dir'" # it is good to log what was cleaned up
echo rm -rf -- "$dir"
done < <(find . -maxdepth 1 -name '[2-9][0-9][0-9][0-9]' -type d -print0 | sort -nrz)
测试后删除echo
之前的rm -rf
。对于您的示例,它提供此输出:
rm -rf -- ./2014
rm -rf -- ./2013
rm -rf -- ./2012
cd /home/backup
将rm -rf
限制在该目录以提高安全性find . -maxdepth 1 -name '[2-9][0-9][0-9][0-9]' -type d
提供与glob sort -nrz
确保首先显示较新的目录,-z
处理find ... -print0
的空终止输出答案 3 :(得分:3)
考虑一下:
find /home/backup/2* -maxdepth 1 | sort -r | awk "NR>3" | xargs rm -rf
仅在 / home / backup /
按字母顺序对列表进行排序,顺序相反。
使用AWK过滤列表中的行数。 NR 指定反向排序行的数量。您可以将该3更改为要保留的行数。因此,如果您只想要最近两年,请将 3 更改为 2 。如果您希望保留最新的10,请将其设为“NR&gt; 10”。
将结果列表附加到命令“rm -rf”。
这里的危险是我建议 rm -rf 。这是有风险的。如果出现问题,您可以删除要保留的内容。我只通过专用用户调用这些命令来减轻这种风险,该专用用户只有删除备份文件的权限(而不是超出)。
这种方法的优点是,当你把它扔进一个cron作业并且时间推进时,它将继续只保留最新的几个目录。所以,我认为这是解决问题的一般方法。
为了测试这个,我创建了一个包含所有相同目录的测试目录。我改变它只是为了看看最后会执行什么,所以我试过了:
find test01/2* -maxdepth 1 | sort -r | awk "NR>4" | xargs echo rm -rf
我使用了NR&gt; 4而不是NR&gt; 3(正如您所希望的那样),因为NR&gt; 4表示我们正在选择要从列表中删除的行数,因此不会删除。
上面的倒数第二个命令将最后阶段改为 echo 它会做什么,但实际上是这样做的。
我在脚本中有一个转储的原始副本,因为我在我的一些服务器上使用它,你可以在这里查看:https://github.com/docdawning/teenybackup
此方法取决于 find 命令产生的字母顺序。在我的例子中,我使用ISO-8601 type dates,它完全适合于在按字母顺序排列时固有的日期排序。您的YYYY类型日期完全符合条件。
我建议您更改备份以存储为tar存档。然后,您可以将 rm -rf 更改为简单的 rm 。这样更安全,但不是万无一失。无论如何,你真的应该把它作为一个专门的非特权用户运行(在我看来你应该为任何调用删除的脚本做)。
请注意,如果您使用
启动它find /home/backup
然后对xargs的调用将包含/ home / backup本身,这将是一场灾难,因为它也会被删除。所以你必须在那条路径内搜索。用以下方法调用它会起作用:
find /home/backup/*
上面给出的2 *只是一种限制搜索操作的方法。
无;这是互联网。小心。大量测试以说服自己。此外,也可能获得一些离线备份。
最后 - 我之前发布了这个作为答案,但是在 / home / backup 而不是 / home / backup / * 来代表基于find命令的致命错误em>或 / home / backup / 2 * 。这导致 / home / backup 也被发送删除,这将是一场灾难。这是一个非常小的区别,我试图在上面清楚。我删除了之前的答案,并将其替换为此答案。
答案 4 :(得分:0)
这是一种方式。
更新了答案。
[dev]$ find backup/* | grep -vE "$(date '+%Y')|$(date +%Y --date='1 year ago')|$(date +%Y --date='2 year ago')" | xargs rm -rfv
removed directory: ‘backup/2012’
removed directory: ‘backup/2013’
removed directory: ‘backup/2014’
答案 5 :(得分:-3)
如果要删除目录,则应键入以下命令
sudo rm -r [folder name]
#in your case it will be
sudo rm -r /home/backup/2012
sudo rm -r /home/backup/2013
sudo rm -r /home/backup/2014