删除除最大尺寸的文件之外的所有带有前缀的文件

删除除最大尺寸的文件之外的所有带有前缀的文件

删除当前目录中带有某个前缀的所有文件(除了带有此前缀但在带有此前缀的所有文件中具有最大大小的文件之外)的最佳方法是什么?

(如果最大的不唯一,则随机保留其中一个,删除其他的。)

例如,当前目录包含以下文件:

-rw-rw----  1 user user 3468 Jan 01 00:00 filea
-rw-rw----  1 user user 3434 Jan 01 00:00 pre_0
-rw-rw-r--  1 user user 9769 Jan 01 00:00 fileb
-rw-rw-r--  1 user user 1950 Jan 01 00:00 filec
-rw-rw-r--  1 user user 8654 Jan 01 00:00 pre_1
-rw-rw----  1 user user 6508 Jan 01 00:00 pre_2

运行命令或脚本删除除最大文件之外的所有带有前缀“pre_”的文件后,当前目录应列出为:

-rw-rw----  1 user user 3468 Jan 01 00:00 filea
-rw-rw-r--  1 user user 9769 Jan 01 00:00 fileb
-rw-rw-r--  1 user user 1950 Jan 01 00:00 filec
-rw-rw-r--  1 user user 8654 Jan 01 00:00 pre_1

答案1

您可以组合使用几个实用程序:

stat -c '%s %n' pre_* | sort -k1,1rn | tail -n +2 | cut -d' ' -f2 | xargs rm

假设 GNU 系统并且没有不寻常的文件名。

  • statpre_*获取所有文件的文件大小和名称,以空格分隔

  • sort根据文件大小对文件进行排序,最大的位于顶部

  • tail -n +2获取除最大文件之外的其余文件

  • cut -d' ' -f2仅获取文件名,rm( xargs rm) 进行删除

答案2

zsh

rm -f pre*(OL[2,-1])
  • OL: 按大小倒序
  • [2,-1]: 仅倒数第二个

与 GNU 实用程序的等效项bash类似于:

eval "files=($(LC_ALL=C ls --quoting-style=shell-always -dS ./pre*))"
rm -f "${files[@]:1}"

您可能希望将其限制为常规文件,因为非常规文件的大小通常没有太大相关性:

rm -f pre*(.OL[2,-1])

(没有直接的 bash+GNU 等价物)。您可能希望包含常规文件的符号链接并考虑符号链接目标的大小:

rm -f pre*(-.OL[2,-1])

使用ls,添加-L选项以考虑符号链接目标的大小。

相关内容