我的文件夹结构很大,需要获取某个子集的大小。我需要计数的目录是通过特定的子目录来定义的:
find . \( -iname a -or ... \) -printf "\"%h\"\n" | xargs -- du -sch | sort -rh
在某种程度上,这种方法效果很好。但是当文件夹太多时,结果中会出现多个总数(使用echo
而不是du
withxargs
会显示输出被分成多行,即调用du
)。
这可能是由某些缓冲区限制引起的。有什么方法可以解决这个问题,以便我在输出中只得到一个总大小?
您的引用没有意义,的输出
find
不会被 shell 解释;也不会使用\n
作为分隔符;您应该始终使用\0
零字节作为分隔符并使用xargs
;-0
零字节永远不能成为文件名或路径的一部分!无论如何,这可能无法解决当前的问题:
命令行具有最大长度;因此,单次调用
du
并带有很多参数可能根本不可能。如果您有 GNU coreutils
du
(如果您使用的是成熟的 Linux,您可能du --version
会这样做),您可以使用du --files0-from=
它从文件中读取文件,或者具体地说,从标准输入中读取文件,当使用-
文件名时:Stéphane 指出,在处理文件之前删除重复项更有意义:
LC_ALL=C
指示 sort 使用“默认的英语-UNIX 语言环境”进行排序。这通常是一个好主意,可以避免根据用户的语言进行不同的排序。我会像这样在TXR Lisp
alpha
中解决这个问题。假设我们要查找的目录具有名为和的子目录beta
的特征gamma
:因为我们使用双星
**
和括号扩展,所以我们必须使用glob*
函数;该glob
函数是同名 POSIX C 库函数的近乎直接的包装器;glob*
在此基础上实现了附加功能。我们的 glob 模式中的尾部斜杠确保仅匹配目录;文件或其他命名的对象
gamma
不计算在内。一旦我们确定了匹配的目录,我们就会遍历它们的父目录(在 的帮助下
dir-name
),并使用 递归处理每一个目录ftw
,通过将它们的总块数乘以 512 来加总访问的对象大小。仅计算一次重复的 inode(指向同一文件的硬链接):
这不仅是在存在硬链接的情况下才有必要,而且在出现同一个目录不止一次的情况下也有可能。假设我们有
path/to/gamma
和path/to/beta
。它们的父目录是同一个目录;我们最终会处理两次。可以改进代码以避免这种情况,但 inode 哈希至少可以防止重复计算。