为什么wc实用程序会生成多行"total"?

Hyp*_*tum 6 shell cygwin

我在从Cygwin运行的shell脚本中使用wc实用程序,我注意到输出中有多行"total".

以下函数用于计算源文件中的行数:

count_curdir_src() {
    find . '(' -name '*.vb' -o -name '*.cs' ')' \
        -a '!' -iname '*.Designer.*' -a '!' -iname '.svn' -print0 | \
    xargs -0 wc -l
}
Run Code Online (Sandbox Code Playgroud)

但它对某个目录的输出如下所示:

$ find . '(' -name '*.vb' -o -name '*.cs' ')' -a '!' -iname '*.Designer.*' -a '!' -iname '.svn' -print0 | xargs -0 wc -l
     19 ./dirA/fileABC.cs
    640 ./dirA/subdir1/fileDEF.cs
    507 ./dirA/subdir1/fileGHI.cs
   2596 ./dirA/subdir1/fileJKL.cs
(...many others...)
     58 ./dirB/fileMNO.cs
     36 ./dirB/subdir1/filePQR.cs
 122200 total
  6022 ./dirB/subdir2/subsubdir/fileSTU.cs
    24 ./dirC/fileVWX.cs
(...)
    36 ./dirZ/Properties/AssemblyInfo.cs
    88 ./dirZ/fileYZ.cs
 25236 total
Run Code Online (Sandbox Code Playgroud)

看起来wc会在过程中的某个位置重置.它不能由文件名或目录名中的空格字符引起,因为我使用该-print0选项.它只发生在我最大的源树上运行时.

那么,这是wc或Cygwin中的错误吗?或者是其他东西?wc联机帮助页说:

打印每个FILE的换行符,单词和字节计数,如果指定了多个FILE,则打印总行数.

它没有提到任何关于多个总线数(中间总计数或其他东西),所以谁应该责怪这里?

Mic*_*and 5

发生的事情是多次xargs运行wcxargs默认情况下,它会在应该执行的命令的每次调用中分配尽可能多的参数,但是如果文件太多,它将在文件的子集上多次运行该命令。

我看到有几种解决方法。第一个是跳过xargs并使用外壳程序,如果文件太多,该文件将中断。这在Cygwin上可能无法正常工作,但看起来像这样:

wc -l $(find . '(' -name '*.vb' -o -name '*.cs' ')' \
    -a '!' -iname '*.Designer.*' -a '!' -iname '.svn' )
Run Code Online (Sandbox Code Playgroud)

并且您还会失去print0功能。

另一种方法是使用awk(或perl)脚本处理find/ xargs组合的输出,跳过“总计”行,然后自行总计。


Jon*_*eet 3

您多次调用 wc - 对于 xargs 提供的每个“批次”输入参数调用一次。每批次您总共得到一个。

一种替代方法是使用临时文件和以下--files0-from选项wc

$ find . '(' -name '*.vb' -o -name '*.cs' ')' -a '!' -iname '*.Designer.*' -a 
    '!' -iname   '.svn' -print0 > files

$ wc --files0-from files
Run Code Online (Sandbox Code Playgroud)