Answers:
您正在寻找管道(|
)。它们是连接多个命令并将一个命令的输出作为输入传递到另一命令的一种方式。在这种情况下,您希望将找到的所有文件名作为输入传递给du
(计算大小)。然而,由于du
预期的文件名和结果find
都只是文字的列表(是的,文本包括文件名,但du
无法知道,所有它认为是文字),你需要使用类似xargs
将于每个文本行,将其作为文件名并将其传递给du
。综合所有这些,我们得到:
find . -name "*.o" | xargs du -sch
您应该始终引用给出的模式find
(就像我在上面所做的:)"*.o"
。如果您不这样做,shell会将扩展*.o
为当前目录中任何匹配文件的名称。在这种情况下,它的工作仅是因为您没有匹配的文件。
的-sch
标志du
记录在man du
:
-c, --total
produce a grand total
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-s, --summarize
display only a total for each argument
但是请注意,这对于包含空格的文件名将失败。对于对象文件,这几乎肯定不会成为问题,但是在将来,如果您还需要处理空格,请使用:
find . -name "*.o" -print0 | xargs -0 du -sch
该-print0
品牌find
打印NULL分隔线和-0
品牌xargs
采取这样的线作为输入。
或者,您可以find
打印尺寸本身,然后求和:
find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'
这也可以解决@Serg在注释中提到的问题,该注释中的参数太多,并且该命令被分解为单独的命令。
如果您正在使用bash
(可能正在使用),则有一种更简单的方法:
shopt -s globstar
du -sch **/*.o
该shopt globstar
命令使**
所有文件和(或)更多子目录匹配。启用后,**/*.o
将匹配名称以结尾的所有文件(和目录).o
,因此我们可以将其直接传递给du
。
请注意,与find
方法不同,此方法将不匹配隐藏文件(名称以开头的文件.
)。要同时匹配这些内容,请执行以下操作:
shopt -s dotglob globstar
du -sch **/*.o
shopt globstar
例子省略了-s
; 我不得不使用shopt -s globstar
类似于您的第二个示例。
shopt OPTION
不带-s
或-u
(或其他选项,请参见help shopt
)的打印机只会输出OPTION的当前值。您需要shopt -s OPTION
打开一个然后shopt -u OPTION
将其关闭。
使用-exec
标志运行du
命令 ;
(每个文件表示)
find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}'
样本输出:
$ find . -name "*.txt" -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes
find
是递归的-表示它遍历所有子目录。如果您只想获取*.o
当前目录中所有文件的总数,请执行
du -b -c *.o
du
,并且会产生多total
行。例如:paste.ubuntu.com/23092752