【问题标题】:Bash command to delete all but last 5 directories [duplicate]Bash命令删除除最后5个目录之外的所有目录[重复]
【发布时间】:2011-05-06 19:50:40
【问题描述】:

可能重复:
Delete all but the most recent X files in bash

我有一个每天创建增量备份的脚本,我需要删除所有备份,但最后 5 个。

例如,我有这个文件夹:

drwxr-xr-x 4 root root 4096 Oct 29 01:10 2010-10-29 drwxr-xr-x 4 根根 4096 Oct 30 01:10 2010-10-30 drwxr-xr-x 4 根根 4096 Oct 31 01:10 2010-10-31 drwxr-xr-x 4 root root 4096 Nov 1 01:10 2010-11-01 drwxr-xr-x 4 root root 4096 Nov 2 01:10 2010-11-02 drwxr-xr-x 4 root root 4096 Nov 3 01:10 2010-11-03 drwxr-xr-x 4 root root 4096 Nov 4 01:10 2010-11-04 drwxr-xr-x 4 root root 4096 Nov 5 01:10 2010-11-05 drwxr-xr-x 4 root root 4096 Nov 6 01:10 2010-11-06 drwxr-xr-x 4 root root 4096 Nov 7 01:10 2010-11-07 drwxr-xr-x 4 root root 4096 Nov 8 01:10 2010-11-08

我只需要维护最后 5 个目录并删除其他目录。命令执行后,我只需要这个:

drwxr-xr-x 4 root root 4096 Nov 4 01:10 2010-11-04 drwxr-xr-x 4 root root 4096 Nov 5 01:10 2010-11-05 drwxr-xr-x 4 root root 4096 Nov 6 01:10 2010-11-06 drwxr-xr-x 4 root root 4096 Nov 7 01:10 2010-11-07 drwxr-xr-x 4 root root 4096 Nov 8 01:10 2010-11-08

我不需要删除前 5 天,我需要删除除最后 5 个目录之外的所有目录 :)

现在我正在使用:

find /backup/increment -maxdepth 1 -type d -mtime +5 -exec rm -rf {} \;

但我需要改进不是基于时间:)

编辑:这是一个全天备份服务器的示例,但我需要一个脚本来删除最后 5 个之前的所有文件夹,因为我的计算机在晚上 00:10 进行备份,但并非所有晚上都完成备份,因为我的计算机整天都无法工作,我需要始终备份最后 5 次 :)

【问题讨论】:

  • 如果不是“基于时间”,你对“后5个”的定义是什么?
  • @dogbane 谢谢,但@MartinStettner 解决方案似乎更优雅:)
  • @David 在主帖中添加了评论。

标签: bash directory


【解决方案1】:

使用tail命令打印从第n行开始的行(选项-n +N):

rm `ls -t | tail -n +6`

ls -t 输出按时间排序的当前目录。 tail -n +6 采用从第 6 行开始的所有行。使用反引号将管道的结果输入到rm 命令中。

旧解决方案,不正确...

使用head 命令,它会打印一些输出的前 n 行:

rm `ls -t1 | head -n 5`

ls -t 输出按时间排序的当前目录。 head -n 5 获取前一个输出的前五个条目。使用反引号将管道的结果输入到rm 命令中。

在申请实时数据之前请先试用:) ...

【讨论】:

  • 您希望使用 tail 代替,用于 last n 行。但是,是的,这个解决方案比我的更简单更好。 :)
  • 怎么样:rm $(ls | sort -r | sed 1,5d);按日期顺序列出姓名;将它们按相反的顺序排序(最近的在前);删除前五行;删除剩下的。
  • @Max:感谢您指出我的错误。幸运的是,tail 有 +N 选项(我不知道),所以我们可以得到所有行但第一个 n
  • @Jonathan:您必须使用ls -t 才能获得按时间排序的结果(或者您必须转发具有正确名称的文件)。您也可以使用ls -t -r 来反转排序,因此不需要sort
  • @MartinStettner:鉴于使用的命名约定,不需要'-t';事实上,它甚至可能给出错误的结果。假设 2010-10-31 的目录在两天前被修改;那么 'ls -t' 会给出错误的目录顺序。
【解决方案2】:

我想到的第一件事。这不优雅:

a=0;
for i in `ls -t`;
do
    a=`expr $a + 1`;
    if [ $a  -gt 5 ]; then
          echo "removing $i";
          rm -rf $i
    fi;
done

【讨论】:

  • 它并不优雅,但它是一个可能的解决方案:)
【解决方案3】:

创建两个具有开始和结束日期的虚拟文件

touch -t 1010290000 before
touch -t 2011042359 after

找到两个虚拟文件之间的所有文件并“rm -rf”结果

find . -newer before \! -newer after -exec rm -rf {} \;

【讨论】:

  • 还有更优雅的解决方案吗? :)
  • 解决方案不会基于日期/时间:)
【解决方案4】:

ls -tr | perl -ne '{@files = ;打印@files[0..$#files-5 ]}' | xargs -n1 echo rm -rf

您将在 rm -rf 之前删除回声以使其工作。

【讨论】:

    【解决方案5】:

    诀窍在于 ls 的 -t 选项,它按修改时间从最新到最旧排序。

    一个非常幼稚的解决方案,使用临时文件,可能会这样:

    ls -t > /tmp/file_list
    num_files_to_keep=5
    # wc -l gets the line count of a file
    # first word of wc output is the actual line count, and that's all we need, so
    # delete everything after the space.
    num_files=`wc -l /tmp/file_list | sed "s/ .*//"`
    #if appropriate you should add a check for num_files < num_files_to_keep
    num_files_to_delete=$(( $num_files - $num_files_to_keep ))
    rm `tail -n $num_files_to_delete /tmp/file_list`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多