查找目录中最大的文件 - 花费大量时间

查找目录中最大的文件 - 花费大量时间

我试图从一个有很多子目录和 N 个文件的目录中找到前 10 个大文件。我的find命令会永远运行,因为它会列出所有文件,然后进入排序模式。我需要更快的执行速度。在我最近一次运行中,列表本身并未在 15 分钟内完成,我不得不终止执行。

我使用了以下find命令,但它们都执行得不够快并且挂起:

find /opt/app -type f -print 2>/dev/null | xargs ls -lS 2>/dev/null |
    sort -k5,5rn | head -10

find /opt/app -xdev -ls | awk '{print $7, $11}' | " sort -rn "}' | head

find /opt/app -type f -exec ls -lS {} + 2>/dev/null | head -n 10 |
    awk '{ print $5, $9 }'

更好的方法是什么?

答案1

在任何情况下,您都需要读取其中所有目录的内容并执行 a lstat(),这意味着读取 inode 数据以获取所有文件的文件大小,然后才能确定哪个文件最大。

磁盘(或网络文件系统的网络)I/O 访问(除非所有信息已缓存在内存中)是花费最多时间的部分。

您的方法做了很多不必要的事情,例如将用户/组 ID 转换为用户/组名称、计算时间戳的日历表示、将字节解码为字符,这些操作将使您的 CPU 和磁盘保持忙碌,但磁盘I/O 可能仍然是瓶颈。

zsh如果您使用 example的 glob 和 glob 限定符,则可以跳过大部分不必要的处理:

ls -ldS /opt/apps/**/*(.DOL[1,10])

请注意,zsh O按长度(表观大小)对文件列表进行排序L,但我们仍然需要-S按大小ls排序S,否则ls会按名称重新排序。通过 GNU 实现ls,您可以使用-U来跳过排序。该实现还支持人类可读大小-h的选项h(使用 KMGTPE...基于 1024 的后缀),此后已被许多其他实现复制。

或者使用(最新的)GNU 工具:

(export LC_ALL=C # avoid decoding bytes into characters and
                 # complex sorting orders. Note that it may affect
                 # the ls -l output format though.
 find /opt/apps -type f -printf '%s/%p\0' |
   sort -srnz |
   head -z |
   cut -zd/ -f2- |
   xargs -r0 ls -ldS)

看看这是否会让事情变得更快。

答案2

sort在所有项目都已排序之前不提供输出。它无法返回输出和新项目,所以就是这样。在我的测试中,GNUsort一旦获得足够的输出来启动其排序算法,就会变得活跃,但会推迟输出,直到所有内容都已排序,因此 和 都sortfind同一时间段内处于活动状态(尽管find较早时处于活动状态,并且sort后来仍然活跃,有重叠)。

我能想到的最快的使用方法find是尽可能避免其他命令和文本处理。因此,使用自身打印大小和名称,find而不是ls多次运行。使用 GNU find (并假设文件名没有换行符):

find /opt/app -xdev -type f -printf "%s %p\n" | sort -k1,1n | head

或者你可以并行运行多个find

(for d in /opt/app/*/; do find "$d" -xdev -type f -printf "%s %p\n" & done; wait) | sort -k1,1n | head

(由于输出交错,这可能是有害的)

sort但在完成工作之前你不会得到任何输出。

答案3

以下代码将给出顶部大文件。

ls -l -R <folder path> | grep -v "^d" | awk '{print $5" "$9}' | sort -nrk1,1 | head -n10 | column -t

如果您还想要文件的完整路径,请尝试以下操作:

find <folder path> -type f -exec du -a {} + | sort -nr | head -10

答案4

不确定这是否是您所需要的,但是:

ls -lR $(密码) | awk'
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=9;下一个}
NF&&f{ 打印 s"/ "$0 }' | egrep -v '^.|^$|^总计\ ' | awk '{print $6,$1$NF}' |排序-nk1 |尾部-n 10
输出:
13307 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_raid.py
14029 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_idrac_eventing.py
15199 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_idrac_users.py
20294 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_idrac_network.py
20851 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/samples/dellemc_get_firmware_inventory.md
35149 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/COPYING.md
49569 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/docs/OMAM_1.0.1_Readme.pdf
65486 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/samples/dellemc_get_system_inventory.md
89526 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/docs/OMAM_1.0.1_Installation_Guide.pdf
438419 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/docs/OMAM_1.0.1_Users_Guide.pdf
只有一个缺点:如果目录包含太多文件,则 ls 无法处理,因此这不起作用。

在我的个人经验中,我注意到 find 的工作时间比这些小命令更长,是的,它不是“最终”版本,可以缩小,但它非常好。

PS 如果删除第一个 AWK,它将仅显示文件名:

ls -lR $(密码) | egrep -v '^.|^$|^总计\ ' |排序-nk5 |尾部-n 10
-rw-rw-r-- 1 pierdolia pierdolia 13307 5 月 14 日 13:22 dellemc_configure_raid.py
-rw-rw-r-- 1 pierdolia pierdolia 14029 5 月 14 日 13:22 dellemc_configure_idrac_eventing.py
-rw-rw-r-- 1 pierdolia pierdolia 15199 5 月 14 日 13:22 dellemc_configure_idrac_users.py
-rw-rw-r-- 1 pierdolia pierdolia 20294 5 月 14 日 13:22 dellemc_configure_idrac_network.py
-rw-rw-r-- 1 pierdolia pierdolia 20851 五月 14 13:22 dellemc_get_firmware_inventory.md
-rw-rw-r-- 1 pierdolia pierdolia 35149 五月 14 13:22 COPYING.md
-rw-rw-r-- 1 pierdolia pierdolia 49569 5 月 14 日 13:22 OMAM_1.0.1_Readme.pdf
-rw-rw-r-- 1 pierdolia pierdolia 65486 5 月 14 日 13:22 dellemc_get_system_inventory.md
-rw-rw-r-- 1 pierdolia pierdolia 89526 5 月 14 日 13:22 OMAM_1.0.1_Installation_Guide.pdf
-rw-rw-r-- 1 pierdolia pierdolia 438419 5 月 14 日 13:22 OMAM_1.0.1_Users_Guide.pdf
或添加额外的 awk:
ls -lR $(密码) | egrep -v '^.|^$|^总计\ ' |排序-nk5 |尾-n 10 | awk '{打印 $5,$NF}'
13307 dellemc_configure_raid.py
14029 dellemc_configure_idrac_eventing.py
15199 dellemc_configure_idrac_users.py
20294 dellemc_configure_idrac_network.py
20851 dellemc_get_firmware_inventory.md
35149 复制.md
49569 OMAM_1.0.1_自述文件.pdf
65486 dellemc_get_system_inventory.md
89526 OMAM_1.0.1_安装指南.pdf
438419 OMAM_1.0.1_Users_Guide.pdf

相关内容