查找最大的文件并自动删除

查找最大的文件并自动删除

我运行此命令来查找最大的文件:

du -Sh | sort -rh | head -5

那我就这么做了-rm rf someFile

有没有办法自动删除从前一个命令找到的文件?

答案1

如果你使用 GNU 工具(这是 Linux 上的标准工具),你可以这样做:

stat --printf '%s\t%n\0' ./* | 
  sort -z -rn | 
  head -z -n 5 | 
  cut  -z -f 2- |
  xargs -0 -r echo rm -f --

(测试后删除“回声”)。

stat命令打印出当前目录中每个文件的文件大小和名称,以制表符分隔,每个记录以 NUL (\0) 字节结尾。

sort命令按相反的数字顺序对每个以 NUL 结尾的记录进行排序。该head命令仅列出前五个此类记录,然后cut从每个记录中删除文件大小字段。

最后xargs采用该(仍然以 NUL 结尾)输入并将其用作 的参数echo rm -f

因为它使用 NUL 作为记录(文件名)终止符,所以它可以处理其中包含任何有效字符的文件名。

如果您想要最小文件大小,那么您可以在和awk之间插入或其他内容。例如statsort

stat --printf '%s\t%n\0' ./* | 
  awk 'BEGIN {ORS = RS = "\0" } ; $1 > 25000000' |
  sort -z -rn | ...

注意:GNUawk没有-zNUL 终止记录的选项,但允许您将记录分隔符设置为您想要的任何内容。我们必须将输出记录分隔符 (ORS) 和输入记录分隔符 (RS) 设置为 NUL。


这是另一个版本,用于find明确将自身限制为常规文件(即排除目录、命名管道、套接字等)仅在指定目录(-maxdepth 1无子目录)中,且大小大于 25M(不需要awk)。

这个版本不需要,stat因为GNUfind也有一个printf功能。顺便说一句,请注意格式字符串的区别 -stat用于%n文件名,而find使用%p.

find . -maxdepth 1 -type f -size +25M -printf '%s\t%p\0' | 
  sort -z -rn | 
  head -z -n 5 | 
  cut  -z -f 2- |
  xargs -0 -r echo rm -f --

要针对不同的目录运行它,请替换.find 命令中的 。例如find /home/web/ ....


shell脚本版本:

#!/bin/sh

for d in "$@" ; do
  find "$d" -maxdepth 1 -type f -size +25M -printf '%s\t%p\0' | 
    sort -z -rn | 
    head -z -n 5 | 
    cut  -z -f 2- |
    xargs -0 -r echo rm -f --
done

将其保存为例如delete-five-largest.sh路径中的某个位置并运行它delete-five-largest.sh /home/web /another/directory /and/yet/another

这将运行find ... 每个目录一次在命令行上指定。这是不是与使用多个路径参数运行一次相同find(看起来像,脚本中find "$@" ...没有任何循环)。for它会删除每个目录中 5 个最大的文件,而在不使用 for 循环的情况下运行它只会删除搜索所有目录时找到的 5 个最大文件。即每个目录五个与总共五个。

答案2

使用最新的 GNU 工具(您已经在使用 GNU 特定选项):

du -S0 . |sort -zrn | sed -z 's@[^/]*@.@;5q' | xargs -r0 echo rm -rf

(如果高兴就删除echo)。

/-0-z为了能够复制具有任意名称的文件/目录。

请注意,大多数rm实现将拒绝删除.(当前工作目录),因此您可能需要从上一级执行此操作并执行以下操作:

du -S0 dir | sort -zrn | sed -z 's@\s*\d+\s*@@;5q' | xargs -r0 echo rm -rf

因此,如果这是最大的文件之一,它可以删除dir(请注意,它也会删除所有子目录)。从您的要求来看,并不清楚这是否真的是您想要的。

现在,如果您只想删除 5 个最大的常规的文件(不包括其他类型的文件,如目录、设备、符号链接...),这只是使用 and 的问题zsh

echo rm -f ./**/*(D.OL[1,5])

OL是按长度(大小,而不是磁盘使用情况)进行反向排序)。

答案3

这里每个文件都有一个(子外壳密集型)循环。将 替换echo为 rm 命令:

du -Sh /your/search/path/ |\
sort -rh |\
head -5 |\
awk '{print $2}' |\
while read file ; do
  echo "$file"
done

在实际的 bash 中工作。但这绝对不是一个好的剧本。由于文件名中存在空格,我肯定会赢得一些评论。 ;)欢迎他们!

如果您熟悉 cron 作业,请定期执行此脚本。

答案4

这是一个简单的答案,希望对您有所帮助 - 'find / -type f -size 1G -exec rm {} \;'这将找到根目录下任何大小超过 1G 的文件(而不是目录),并将其删除。例如,如果您需要按名称选择文件,则可以在 exec 之后添加额外的文件排序。大小可以更改为 M(兆字节)、k(千字节)、c(字节)。有很多选项可供查找,这是一个强大的命令,请查看手册页! :)

相关内容