如何在 Linux 中删除除 10 个最新文件之外的所有文件?

use*_*814 57 linux

我试图保持一个充满日志文件的目录可管理。每晚,我想删除除最近的 10 个之外的所有内容。如何在单个命令中执行此操作?

Isa*_*man 67

要获得便携且可靠的解决方案,请尝试以下操作:

ls -1tr | head -n -10 | xargs -d '\n' rm -f --
Run Code Online (Sandbox Code Playgroud)

tail -n -10在其他的答案中的一个语法似乎并没有工作无处不在(即,不是我的RHEL5系统)。

并在命令行上使用$()或运行风险``rm

  1. 用空格分割文件名,和
  2. 超过最大命令行字符限制。

xargs修复了这两个问题,因为它会自动计算出它可以在字符限制内传递多少个参数,并且-d '\n'它只会在输入的行边界处拆分。从技术上讲,这仍然会导致带有换行符的文件名出现问题,但这远不如带空格的文件名常见,而且换行符的唯一方法会复杂得多,如果不是 perl,可能至少涉及 awk。

如果您没有 xargs(可能是旧的 AIX 系统?),您可以将其设为循环:

ls -1tr | head -n -10 | while IFS= read -r f; do
  rm -f "$f"
done
Run Code Online (Sandbox Code Playgroud)

这会慢一点,因为它rm为每个文件生成一个单独的文件,但仍然会避免上面的警告 1 和 2(但仍然会受到文件名换行的影响)。


Dan*_*mer 21

您想要包含在脚本中的代码是

 rm -f $(ls -1t /path/to/your/logs/ | tail -n +11)
Run Code Online (Sandbox Code Playgroud)

-1(数字1)选项打印在一行上的每个文件,是安全的。告诉它在不返回任何内容时忽略不存在的文件的-f选项。rmls

  • 您是否使用了正确的路径?显然 `/path/to/your/logs` 只是为了让你输入正确的路径。要查找错误,请执行部分 `ls -t /path/...` 和 `ls -t /path/... | tail -n +11` 单独检查结果是否正确。 (2认同)
  • 我认为您的答案非常危险 `ls` 打印文件名,而不是路径,因此您的 `rm -f` 将尝试删除当前目录中的文件 (2认同)

The*_*One 18

显然解析ls是邪恶的

如果每个文件都是每天创建的,并且您想保留过去 10 天内创建的文件,您可以执行以下操作:

find /path/to/files -mtime 10 -delete
Run Code Online (Sandbox Code Playgroud)

或者,如果每个文件都是任意创建的:

find /path/to/files -maxdepth 1 -type f -printf '%Ts\t%P\n' | sort -n | head -n -10 | cut -f 2- | xargs rm -rf
Run Code Online (Sandbox Code Playgroud)

  • `-mtime 10 -delete` 只删除 10 天前修改的文件。旧文件不会被删除。`-mtime +11 -delete` 将删除 11 天或更多天前修改过的文件,留下最后 10 天的日志文件。 (7认同)
  • 我认为在 `printf` 上需要使用 `%p` 而不是 `%P`,以便文件具有完整路径。否则`rm -rf` 不起作用。 (2认同)

Bil*_*hor 9

像 logrotate 这样的工具可以为您做到这一点。它使日志管理更加容易。您还可以包括额外的清理例程,如 halo 建议的那样。