我的文件夹结构很大,需要获取某个子集的大小。我需要计数的目录是通过特定的子目录来定义的:

find . \( -iname a -or ... \) -printf "\"%h\"\n" | xargs -- du -sch | sort -rh 

在某种程度上,这种方法效果很好。但是当文件夹太多时,结果中会出现多个总数(使用echo而不是duwithxargs会显示输出被分成多行,即调用du)。

这可能是由某些缓冲区限制引起的。有什么方法可以解决这个问题,以便我在输出中只得到一个总大小?

2

  • 1
    您希望输出什么?您可以在问题中提供一个例子吗?


    – 

  • 是的,请添加预期输出的示例。另外,仅供参考,"\"foo\""您可以使用单引号:-printf '"%h"\n',而不是繁琐的。


    – 


最佳答案
1

您的引用没有意义,的输出find不会被 shell 解释;也不会使用\n作​​为分隔符;您应该始终使用\0零字节作为分隔符并使用xargs-0零字节永远不能成为文件名或路径的一部分!

无论如何,这可能无法解决当前的问题:

命令行具有最大长度;因此,单次调用du并带有很多参数可能根本不可能。

如果您有 GNU coreutils du(如果您使用的是成熟的 Linux,您可能du --version会这样做),您可以使用du --files0-from=它从文件中读取文件,或者具体地说,从标准输入中读取文件,当使用-文件名时:

find . \( CRITERIA \) -printf '%h\0' | du -sch --files0-from=- | sort -rh

Stéphane 指出,在处理文件之前删除重复项更有意义:

find . \( CRITERIA \) -printf '%h\0' | LC_ALL=C sort -zu | du -sch --files0-from=-

LC_ALL=C指示 sort 使用“默认的英语-UNIX 语言环境”进行排序。这通常是一个好主意,可以避免根据用户的语言进行不同的排序。

6

  • 2
    xargs有自己的引号解释,因此如果文件路径不包含引号字符,则引用是有意义的。另请注意,OP 似乎想要获取包含名为 的文件的目录的磁盘使用情况a,因此您可能需要-printf '%h\0' | LC_ALL=C sort -zu | du --files0-from=- ...


    – 

  • 谢谢,已经修复!


    – 

  • 无论如何,所有-print0-printf-h-z都是 GNU 扩展(尽管被添加到 POSIX 标准的 2024 版中并且-0 --files0-from/现在也出现在一些非 GNU 实现中)-iname-print0xargs -r0-iname-h


    – 


  • 1
    sort -u不仅仅涉及排序,还涉及删除重复项。


    – 

  • 我需要引号,因为有些文件名包含空格,没有引号du就找不到它们。但使用 \0 终止符du --files0-from=-效果很好。谢谢!


    –