我有一个脚本来每天创建增量备份,我需要删除所有备份,但最后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个目录以外的所有目录:)
现在我正在使用:
find /backup/increment -maxdepth 1 -type d -mtime +5 -exec rm -rf {} \;
但我需要改进而不是基于时间:)
编辑:这是一个整天进行备份的服务器的示例,但是我需要一个脚本来删除过去5之前的所有文件夹,因为我的计算机在晚上00:10进行备份,但不是所有的夜晚备份都完成了,因为我的电脑一直没有工作,我需要总是最后5个备份:)
答案 0 :(得分:35)
使用tail
命令打印以 n 行开头的行(选项-n +N
):
rm `ls -t | tail -n +6`
ls -t
输出按时间排序的当前目录。 tail -n +6
从第6行开始。使用反引号进行引用会将管道的结果输入rm
命令。
OLD SOLUTION,不正确......
使用head
命令打印某些输出的第一行 n 行:
rm `ls -t1 | head -n 5`
ls -t
输出按时间排序的当前目录。 head -n 5
获取前一输出的前五个条目。使用反引号进行引用会将管道的结果输入rm
命令。
在申请实时数据之前请先试用:) ...
答案 1 :(得分:1)
我想到的第一件事就是。这不优雅:
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
答案 2 :(得分:0)
使用开始日期和结束日期创建两个虚拟文件
touch -t 1010290000 before
touch -t 2011042359 after
找到2个虚拟文件和“rm -rf”结果之间的所有文件
find . -newer before \! -newer after -exec rm -rf {} \;
答案 3 :(得分:0)
ls -tr | perl -ne'{@files =<&gt ;; print @files [0 .. $#files-5]}'| xargs -n1 echo rm -rf
你可以在rm -rf之前移除echo以使其工作。
答案 4 :(得分:0)
技巧将是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`