保留备份脚本中的n个最新目录

abu*_*buy 11 unix linux bash backup

我有/home/backup/存储年度备份的目录.在备份文件夹中,我们有以下目录:

/home/backup/2012
/home/backup/2013
/home/backup/2014
/home/backup/2015
/home/backup/2016
/home/backup/2017
Run Code Online (Sandbox Code Playgroud)

每年我都要清理数据,只保留最后三年的备份.

在上面的例子中,我必须删除:

/home/backup/2012
/home/backup/2013
/home/backup/2014
Run Code Online (Sandbox Code Playgroud)

找到要删除的目录的最佳方法是什么?我有这个,但它不起作用:

find /home/ecentrix/recording/ -maxdepth 1 -mindepth 1 -type d -ctime +1095 -exec rm -rf {} \;
Run Code Online (Sandbox Code Playgroud)

你们有另一个想法吗?

bis*_*hop 8

由于您的目录具有明确定义的整数名称,因此我只使用bash来计算适当的目标:

mkdir -p backup/201{2..7} # just for testing

cd backup
rm -fr $(seq 2012 $(( $(date +"%Y") - 3)))
Run Code Online (Sandbox Code Playgroud)

seq生成从2012年到当前年份减去3的数字列表,然后传递给rm它们.


cod*_*ter 5

更通用的解决方案

我认为最好按降序遍历目录,然后删除第三个之后的目录。这样,当脚本一次又一次运行时,就不会有丢失目录的危险:

#!/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)
Run Code Online (Sandbox Code Playgroud)

测试后去掉echo之前的。rm -rf对于您的示例,它给出以下输出:

rm -rf -- ./2014
rm -rf -- ./2013
rm -rf -- ./2012
Run Code Online (Sandbox Code Playgroud)
  • cd /home/backuprm -rf为了额外的安全性,仅限于该目录
  • find . -maxdepth 1 -name '[2-9][0-9][0-9][0-9]' -type d给出与 glob 匹配的顶级目录
  • sort -nrz确保较新的目录优先,-z处理空终止的输出find ... -print0
  • 该解决方案不会对年份进行硬编码 - 它只是假设要删除的目录以数字可排序的方式命名
  • 它对备份目录中存在的任何其他文件或目录具有弹性
  • 如果脚本一次又一次运行,不会有任何副作用
  • 这可以轻松扩展以支持备份目录的不同命名约定 - 只需更改 glob 表达式