生物信息学linux

【awk】用 ls 结合 awk 统计目录文件大小

2022-06-18  本文已影响0人  Bogon

你一定遇到过这种情况,在一个有几百万文件的目录中执行ls命令,ls就卡在那了,是吧?
但是,用ls -l -f命令可以立即显示出文件。

如果你想删除当前目录中的所有文件,使用如下命令:

ls  -l  -f | xargs rm

在清理大量不需要的文件后,会留下一个巨大稀疏的目录对象(directory object)。
假如一个目录下有300万个文件,除了这些文件占用空间外,目录对象本身也会占用超过100M的空间。
你也许想重建一个目录来回收那100M空间。但是,如果目录是/tmp,那就要小心了,只能在单用户模式下操作。

ls命令为什么会卡住?

默认情况下,ls命令会将输出排序。为了排序,ls命令先将所有文件的名称读入内存。当遇到一个非常大的目录时,它就在那里不断地读入文件名,并且内存占用越来越大,直到将所有文件一次性以字母数字顺序列出来。

而 ls -l -f 命令并不执行排序操作,只是读取目录然后立即显示文件。

下面举个例子,有个目录,包含300万个文件,文件名称形如test_file_a_1, test_file_a_2, ..., test_file_a_3000000. 用Perl脚本以文件名中的数字编号顺序来创建这些文件。

可以用 ls -l -f 命令立即列出头几个文件:

$ time  ls  -l  -f  |  head
.
..
test_file_a_2531963
test_file_a_467778
test_file_a_2677947
test_file_a_329896
test_file_a_835701
test_file_a_1266060
test_file_a_261887
test_file_a_311007

real    0m0.006s
user    0m0.000s
sys     0m0.008s

现在,去掉上面命令中的-l和-f标志,ls命令花了大约10000倍长的时间:

$ time /bin/ls | head
test_file_a_1
test_file_a_10
test_file_a_100
test_file_a_1000
test_file_a_10000
test_file_a_100000
test_file_a_1000000
test_file_a_1000001
test_file_a_1000002
test_file_a_1000003

real    0m57.880s
user    0m55.644s
sys     0m2.121s

除了变得更慢外,后者还占用了大量内存。
当ls命令真正开始打印文件名的时候,它已经在内存中存储了300万个文件名,使用了大约507M内存。
相反,ls -l -f 命令内存占用从未超过4.5M,少了100倍。

当你的文件夹下面文件特别多,尤其是文件名也比较长的时候,它会消耗掉非常多的block。当你遍历文件夹的时候,如果Page Cache中没有命中你要访问的block,就会穿透到磁盘上进行实际的IO。在你的角度来看,就是你执行完ls后,卡住了。

当一个 目录下有无数小文件时,你发现你用 du -sh /path/to 会很久有不出结果,甚至会因为 SSH timeout 而被退出当前shell 。

那么 试试这个:

ls -l  /path/to/  |  grep -wv "total"  | awk  '{sum+=$5}  END{print sum/(1024^3)}'

当 /path/to/ 目录下有上百万个小文件时,基本就没法使用 du -sh 了 ,但是你 ls -l 就没问题 。

image.png

适用场景:

  1. 统计目录下为 小文件,且数量巨大
  2. 统计目录下都是文件,如果有子目录,那么只会统计该子目录本身大小,而不是子目录下文件大小

那么你肯定会问,我确实要保存许许多多的文件,我该怎么办?
其实也很简单,多创建一些文件夹就好了,一个目录下别存太多,就不会有这个问题了。
工程实践中,一般的做法就是通过一级甚至是二级hash把文件散列到多个目录中,把单目录文件数量控制在十万或万以下。

参考

我一定要让所有人都知道awk这个实用操作
https://www.cnblogs.com/jujujulie/p/15742730.html

使用 AWK 统计不同文件格式的文件大小总和
https://blog.51cto.com/liubin0505star/2584404

用wk数组做统计分析
https://blog.51cto.com/lidao/1912219

Linux 统计文件的行数
http://www.manongjc.com/detail/51-hbieyrvumhknpnn.html

通过awk 统计字母频率
https://www.lxlinux.net/9822.html

awk算术运算一例:统计hdfs上某段时间内的文件大小
https://www.cnblogs.com/dyllove98/p/3239213.html

Linux查看文件大小的几种方法示例
https://www.cnblogs.com/renmengkai/p/9452883.html

Awk 学习笔记——基础篇
https://blog.csdn.net/longwen7/article/details/6336757

文件过多时ls命令为什么会卡住?
https://zhuanlan.zhihu.com/p/134207214

Linux 离奇磁盘爆满,如何解决?
https://zhuanlan.zhihu.com/p/111412537

Large Directory Causes ls to "Hang"
http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang

文件处理命令:awk
https://www.programminghunter.com/article/89221444707

Linux中du命令和df命令有什么区别?
https://baijiahao.baidu.com/s?id=1709666864674037357&wfr=spider&for=pc

df和du显示的磁盘空间使用情况不一致的原因及处理
https://www.cnblogs.com/heyonggang/p/3644736.html
https://help.aliyun.com/document_detail/96228.html

Linux系统磁盘空间占满,df和du结果不一致
https://www.jianshu.com/p/3164d1a53e34

上一篇 下一篇

猜你喜欢

热点阅读