我试图从一个有很多子目录和 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
一旦获得足够的输出来启动其排序算法,就会变得活跃,但会推迟输出,直到所有内容都已排序,因此 和 都sort
在find
同一时间段内处于活动状态(尽管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