删除所有带有前缀的文件,最大的文件除外

D. *_*hen 6 command-line wildcards files

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

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

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

-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
Run Code Online (Sandbox Code Playgroud)

运行命令或脚本删除除最大文件之外的所有带有前缀“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
Run Code Online (Sandbox Code Playgroud)

hee*_*ayl 7

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

stat -c '%s %n' pre_* | sort -k1,1rn | tail -n +2 | cut -d' ' -f2 | xargs rm
Run Code Online (Sandbox Code Playgroud)

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

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

  • sort 根据文件大小对文件进行排序,最大的一个到顶部

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

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


Sté*_*las 7

zsh

rm -f pre*(OL[2,-1])
Run Code Online (Sandbox Code Playgroud)
  • OL: 按大小倒序
  • [2,-1]: 倒数第二

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

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

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

rm -f pre*(.OL[2,-1])
Run Code Online (Sandbox Code Playgroud)

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

rm -f pre*(-.OL[2,-1])
Run Code Online (Sandbox Code Playgroud)

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