查找目录分支中某些文件的总大小

mba*_*off 210 size directory directory-structure files

假设有一个图像存储目录,例如,./photos/john_doe,其中有多个子目录,许多特定文件驻留在其中(例如,*.jpg)。如何计算john_doe分支下这些文件的摘要大小?

我试过du -hs ./photos/john_doe/*/*.jpg,但这仅显示单个文件。此外,这仅跟踪john_doe目录的第一个嵌套级别,例如john_doe/june/,但会跳过john_doe/june/outrageous/

那么,我如何遍历整个分支,总结某些文件的大小?

SHW*_*SHW 269

find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
Run Code Online (Sandbox Code Playgroud)

如果du由于文件列表很长而需要多次调用,则会报告多个总数并需要求和。

  • find -iname 'file*' -exec du -cb {} + | grep 总计$ | 切-f1 | 粘贴 -sd+ - | bc # 总字节大小 (12认同)
  • 如果您的系统在其他语言下工作,那么您需要将 total$ 更改为其他词,例如波兰语中的 razem$。 (4认同)
  • @MichalČizmazia 一些 shell(例如 Windows 的 Git Bash)不带有 `bc`,所以这里有一个更便携的解决方案:`find -name '*.jpg' -type f -exec du -bc {} + | grep 总计$ | 切-f1 | awk '{ 总计 += $1 }; END { 打印总数 }'` (4认同)
  • “find”命令末尾的“+”有什么作用?我在“man find”中找不到任何提及它的内容。 (3认同)
  • 您可以将 `LC_ALL=POSIX` 作为前缀添加到 always grep 中,如下所示: `LC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep 总计$` (2认同)
  • 如果您没有使用 `-name`,那么将 grep 更改为 `grep -P "\ttotal$"`,否则它也会捕获所有以“total”结尾的文件。 (2认同)

Lev*_*von 79

du -ch public_html/images/*.jpg | grep total
20M total
Run Code Online (Sandbox Code Playgroud)

给我.jpg这个目录中我的文件的总使用量。

要处理多个目录,您可能必须以find某种方式将其结合起来。

您可能会发现du 命令示例很有用(它还包括find

  • 这不会遍历底层目录? (4认同)
  • 要获取子目录中的图像,不能使用“**/*.jpg”吗? (3认同)
  • 这比公认的解决方案更容易输入,但只对了一半,它不会在子目录中包含图像。很高兴知道所有文件是否都在一个目录中。 (2认同)

Gil*_*il' 42

首先,您需要两件事:

  • -c选项du,告诉它产生总计;
  • 任一**激活指令)或find例如),或横向子目录。
du -ch -- **/*.jpg | tail -n 1
Run Code Online (Sandbox Code Playgroud)

  • @EricFournie 但是,在处理大约 30 万个文本文件时,我遇到了“参数列表太长”错误。 (3认同)
  • 很好的回复。比使用 find 更简单(只要 * 或 ** 匹配目录结构) (2认同)

rin*_*eal 37

最终答案是:

{ find <DIR> -type f -name "*.<EXT>" -printf "%s+"; echo 0; } | bc
Run Code Online (Sandbox Code Playgroud)

甚至更快的版本,不受 RAM 限制,但这需要具有 bignum 支持的 GNU AWK:

find <DIR> -type f -name "*.<EXT>" -printf "%s\n" | gawk -M '{t+=$1}END{print t}'
Run Code Online (Sandbox Code Playgroud)

该版本具有以下特点:

  • find指定您要查找的文件的所有功能
  • 支持数百万个文件
    • 此处的其他答案受参数列表的最大长度限制
  • 只产生 3 个简单的进程,管道吞吐量最小
    • 这里的许多答案产生了 C+N 个进程,其中 C 是某个常数,N 是文件数
  • 不打扰字符串操作
    • 这个版本不做任何grepping,或regexing
    • 好吧,find做一个简单的文件名通配符匹配
  • 任选地格式化的总和为人类可读的形式(例如5.5K176.7M,...)
    • 做那个附加 | numfmt --to=si


Jan*_*Jan 13

到目前为止给出的答案没有考虑到从 find 传递给 du 的文件列表可能太长,以至于 find 自动将列表拆分为块,导致多次出现total.

您可以grep total(语言环境!)并手动总结,或使用不同的命令。AFAIK 只有两种方法可以获取 find 找到的所有文件的总计(以千字节为单位):
find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'

说明
find . -type f -iname '*.jpg' -print0:查找所有扩展名为 jpg 的文件,不分大小写(即 *.jpg、*.JPG、*.Jpg...)并输出它们(以空字符结尾)。
xargs -r0 du -a: -r: 即使没有传递参数,Xargs 也会调用命令,这是 -r 阻止的。-0 表示以空字符结尾的字符串(不以换行符结尾)。
awk '{sum+=$1} END {print sum}': 总结上一条命令输出的文件大小

作为参考,另一种方式是
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-