9

我有一大组目录,我正在尝试计算数百个 .txt 文件的总大小。我试过这个,它最有效:

find . -name *.txt | xargs du -hc

但是最后我没有给我一个总数,而是得到了几个。我的猜测是管道一次只会传递这么多行的 find 输出,而 du 只是在每个批次上进行操作。有没有解决的办法?

谢谢!亚历克斯

4

7 回答 7

12

对 du 使用 --files0-from 选项怎么样?您必须适当地生成以空字符结尾的文件输出:

find . -name "*txt" -exec echo -n -e {}"\0" \; | du -hc --files0-from=-

在我的系统上正常工作。

于 2009-08-24T17:52:29.413 回答
7
find . -print0 -iname '*.txt' | du --files0-from=-

如果你想有几个不同的扩展来搜索,最好这样做:

find . -type f -print0 | grep -azZEi '\.(te?xt|rtf|docx?|wps)$' | du --files0-from=-
于 2010-10-21T19:57:01.190 回答
6

xargs 程序将事情分成批次,以解决由于 unix 命令行的最大长度而导致的限制。它仍然比一次运行一个子命令更有效,但是对于一长串输入,它会运行命令足够多次,每次“运行”都足够短,不会引起问题。

因此,您可能会看到 xargs 需要运行的每个“批次”输出一行。

因为您可能会发现它有用/有趣,所以可以在此处在线找到手册页:http ://unixhelp.ed.ac.uk/CGI/man-cgi?xargs


需要注意的另一件事(这可能是您的帖子中的错字或我的误解)是您的“* .txt”未转义/引用。即,你有

find . -name *.txt | xargs du -hc

你可能想要的地方

find . -name \*.txt | xargs du -hc

不同之处在于命令行可能会将 * 扩展到匹配的文件名列表中......而不是将 * 传递给 find,后者会将其用作模式。

于 2009-08-24T17:31:27.227 回答
3

另一个简单的解决方案:

find . -name *.txt -print0 | xargs -0 du -hc
于 2012-08-23T16:00:54.530 回答
1

一种替代解决方案是使用 bashfor循环:

for i in `find . -name '*.txt'`; do du -hc $i | grep -v 'total'; done

当您需要更多地控制循环中发生的事情时,这很有用。

于 2015-03-30T10:45:00.470 回答
0

xargs 将其输入分解为大小合理的块 - 您所看到的是每个块的总数。检查 xargs 的手册页,了解配置其输入处理的方法。

于 2009-08-24T17:31:21.750 回答
0

一种替代解决方案是使用 awk:

find . -name "*.txt" -exec ls -lt {} \; | awk -F " " 'BEGIN { sum=0 } { sum+=$5 } END { print sum }'
于 2009-08-24T17:47:36.587 回答