按字母顺序排序后,删除除了N个文件以外的所有文件的Bash脚本

15

标题很难解释。

我有一个Bash脚本,每天运行一次,将一个文件夹备份到一个zip文件中。 这些zip文件的名称为worldYYYYMMDD.zip,其中YYYYMMDD是备份日期。 我想要做的是删除除最近的5个备份之外的所有备份。按字母顺序排序文件将首先列出最旧的文件,所以我基本上需要在按字母顺序排序时删除除最后5个文件之外的所有文件。


这是打算手动完成,每当你觉得备份太多时,还是每次运行bash脚本时自动完成的? - cledoux
@chaz8705 我会双向使用它 - sgtFloyd
请注意,大多数这些答案在文件名包含空格时会失败。 - Dennis Williamson
5个回答

25
以下一行应该能解决问题。
ls world*.zip | head -n -5 | xargs -r rm
  • ls world*.zip: 按字母顺序列出文件alphabetically
  • head -n -5: 过滤掉除了最后5行以外的所有行
  • xargs -r rm: 删除每个给定的文件。 -r: 如果输入为空,则不运行rm

2
嗯...包括 ls -AF world*.zip 会更好。 - Benoit
1
“ls -F” 在文件名末尾添加了无用的字符,不应该使用。因为没有隐藏文件,“-A” 也不是必需的。 - Fred Foo
@larsmans,谢谢,已更新。(我只是假设他想要它,因为他在原始帖子中提到了它。) - aioobe
一定要删除 -F - Dennis Williamson
1
如果文件数量少于5个,请确保 xargs -r rm 命令的最后一个参数有效,否则将会出现错误。 - dalyons

3
这个怎么样:
find /your/directory -name 'world*.zip' -mtime +5 | xargs rm

在进行操作之前,请先测试一下。这将删除所有早于5天的world*.zip文件。因此,逻辑与您拥有的不同。


尽管这样最合理,但我不想基于文件日期进行删除。如果备份脚本失败,我仍然希望保留最近的5个备份,因此aioobe的答案对我来说是最好的。 - sgtFloyd
{} 应该被转义或用引号括起来。我知道在这种情况下它可以工作,但这仍然是良好的实践,并且被 man 手册推荐。 - cledoux

1

我现在无法测试它,因为我没有Linux机器,但我认为应该是这样的:

rm `ls -A | head -5`

0
ls | grep ".*[\.]zip" | sort | tail -n-5 | while read file; do rm $file; done
  • sort 命令用于对文件进行排序
  • tail -n-5 命令返回除了最近的 5 个之外的所有内容
  • while 循环用于执行删除操作

1
不。这将删除5个文件。作者想要除了5个以外的所有文件,而grep -c则计算文件数。 - Benoit
@Benoit是一个我已经修复的打字错误。 - moinudin
1
可能使用 echo world*.zip | sort | tail -n -5 | xargs rm 更为高效。 - Benoit
grep 是不必要的。@Benoit:echo 输出在一行上,所以排序是无效的。 - Dennis Williamson

0

ls world*.zip | sort -r | tail n+5 | xargs rm

sort -r 会按照相反的顺序排序,所以最新的文件将排在前面

tail n+5 将输出从第五行开始的所有行

xargs rm 将删除这些文件。Xargs 用于将 stdin 作为参数传递给 rm。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接