Bash 命令删除除最后 5 个目录之外的所有目录

发布于 2024-10-01 08:57:39 字数 1596 浏览 0 评论 0原文

可能的重复:
删除 bash 中除最新 X 文件之外的所有文件

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

例如,我有以下文件夹:

drwxr-xr-x  4 root root 4096 Oct 29 01:10 2010-10-29
drwxr-xr-x  4 root root 4096 Oct 30 01:10 2010-10-30
drwxr-xr-x  4 root root 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 个目录之外的所有目录:)

现在我正在使用:

查找/备份/增量-maxdepth 1 -type d -mtime +5 -exec rm -rf {} \;

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

编辑: 这是一个全天备份的服务器的示例,但我需要一个脚本来删除最后 5 个之前的所有文件夹因为我的电脑在晚上 00:10 进行备份,但不是所有晚上都备份完成,因为我的电脑不是整天都在工作,而且我需要始终保留最后 5 个备份:)

Possible Duplicate:
Delete all but the most recent X files in bash

I have a script to create incremental backups daily and I need to delete all backups but last 5.

For example, I have this folders:

drwxr-xr-x  4 root root 4096 Oct 29 01:10 2010-10-29
drwxr-xr-x  4 root root 4096 Oct 30 01:10 2010-10-30
drwxr-xr-x  4 root root 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

And I need to maintain only the last 5 directories and delete the others. After command execute, I need to have only this:

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

I don't need to delete previous to 5 days, I need to delete all except 5 last directories :)

Now I'm using:


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

But I need to improved not based in time :)

EDIT: This is an example for a server that do backups all days, but I need an script that delete all folders previous to last 5 because my computer do backups at 00:10 at night, but not all nights the backup is done it, because my computer isn't working all days, and I need to have always the last 5 backups :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

奢华的一滴泪 2024-10-08 08:57:39

使用 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 命令中。

在应用于实时数据之前请先尝试:) ...

use the tail command to print lines starting with the n th line (Option -n +N):

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

ls -t outputs the current directory sorted by time. tail -n +6 takes al lines starting with the 6th line. Quoting with backticks feeds the result of the pipe into the rm command.

OLD SOLUTION, not correct ...

use the head command, which prints the first n lines of some output:

rm `ls -t1 | head -n 5`

ls -t outputs the current directory sorted by time. head -n 5 takes the first five entries of the previous output. Quoting with backticks feeds the result of the pipe into the rm command.

Please try out first before applying to live data :) ...

Spring初心 2024-10-08 08:57:39

我首先想到的是。这并不优雅:

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

The first thing that came to my mind. It's not elegant:

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
蹲在坟头点根烟 2024-10-08 08:57:39

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

touch -t 1010290000 before
touch -t 2011042359 after

查找这两个虚拟文件之间的所有文件和“rm -rf”结果

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

create two dummy files with the start and the end date

touch -t 1010290000 before
touch -t 2011042359 after

find all the files between the 2 dummy files and "rm -rf" the result

find . -newer before \! -newer after -exec rm -rf {} \;
夏日浅笑〃 2024-10-08 08:57:39

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

您可以删除 rm -rf 之前的 echo 以使其正常工作。

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

You would remove the echo before the rm -rf to get it to work.

望笑 2024-10-08 08:57:39

诀窍是 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`

The trick will be the -t option to ls, which sorts by modification time, from newest to oldest.

A really naive solution, using a temporary file, might go this way:

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`
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文