我的文件夹结构很大,需要获取某个子集的大小。我需要计数的目录是通过特定的子目录来定义的:
find . \( -iname a -or ... \) -printf "\"%h\"\n" | xargs -- du -sch | sort -rh
在某种程度上,这种方法效果很好。但是当文件夹太多时,结果中会出现多个总数(使用echo
而不是du
withxargs
会显示输出被分成多行,即调用du
)。
这可能是由某些缓冲区限制引起的。有什么方法可以解决这个问题,以便我在输出中只得到一个总大小?
2
最佳答案
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
-print0
xargs -r0
-iname
-h
–
-
1这
sort -u
不仅仅涉及排序,还涉及删除重复项。
– -
我需要引号,因为有些文件名包含空格,没有引号
du
就找不到它们。但使用 \0 终止符du --files0-from=-
效果很好。谢谢!
–
|
–
"\"foo\""
您可以使用单引号:-printf '"%h"\n'
,而不是繁琐的。–
♦
|