我运行此命令来查找最大的文件:
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
之间插入或其他内容。例如stat
sort
stat --printf '%s\t%n\0' ./* |
awk 'BEGIN {ORS = RS = "\0" } ; $1 > 25000000' |
sort -z -rn | ...
注意:GNUawk
没有-z
NUL 终止记录的选项,但允许您将记录分隔符设置为您想要的任何内容。我们必须将输出记录分隔符 (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(字节)。有很多选项可供查找,这是一个强大的命令,请查看手册页! :)