为什么wc实用程序会用“total”生成多行?
我在一个从Cygwin运行的shell脚本中使用了wc实用程序,并且我注意到其输出中有多行“total”。
以下函数用于计算我的源文件中的行数:
count_curdir_src() {
find . '(' -name '*.vb' -o -name '*.cs' ')'
-a '!' -iname '*.Designer.*' -a '!' -iname '.svn' -print0 |
xargs -0 wc -l
}
但是它对于某个目录的输出如下所示:
$ 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
它看起来像wc重置过程中的某个地方。 它不能由文件名或目录名称中的空格字符引起,因为我使用-print0
选项。 它只发生在我最大的源代码树上时。
那么,这是wc中还是Cygwin中的错误? 或者是其他东西? wc手册页说:
为每个FILE打印换行符,字和字节计数,如果指定了多个FILE,则打印总行。
它没有提到任何关于多条总线(中间总数或某物)的事情,那么谁来责怪呢?
你多次调用wc - 对xargs提供的每个“批处理”输入参数一次。 你每批得到一个总数。
一种替代方法是使用临时文件和wc
: --files0-from
选项:
$ find . '(' -name '*.vb' -o -name '*.cs' ')' -a '!' -iname '*.Designer.*' -a
'!' -iname '.svn' -print0 > files
$ wc --files0-from files
发生什么事是xargs
多次运行wc
。 默认情况下, xargs
批量尽可能多的参数,因为它认为它可以应用到它应该运行的命令的每个调用中,但是如果文件太多,它会在文件的子集上多次运行该命令。
有几种方法可以解决这个问题。 第一个,如果你有太多文件会中断,就是跳过xargs
并使用shell。 这在Cygwin上可能无法正常工作,但看起来像这样:
wc -l $(find . '(' -name '*.vb' -o -name '*.cs' ')'
-a '!' -iname '*.Designer.*' -a '!' -iname '.svn' )
而且你也失去了print0的能力。
另一种方法是使用awk
(或perl
)脚本处理find
/ xargs
组合的输出,跳过“总计”行,并自己总结总计。
命令行长度在cygwin下比在标准的linux下更受限制,并且xargs
必须将输入分割以遵守这些限制。 您可以使用xargs --show-limits
来检查xargs --show-limits
:
在cygwin上:
$ xargs --show-limits < /dev/null
Your environment variables take up 4913 bytes
POSIX upper limit on argument length (this system): 25039
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 20126
Size of command buffer we are actually using: 25039
在centos上:
$ xargs --show-limits < /dev/null
Your environment variables take up 1816 bytes
POSIX upper limit on argument length (this system): 2617576
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2615760
Size of command buffer we are actually using: 131072
并且建立在@ JonSkeet的答案上,你不需要创建一个额外的文件,你可以直接将查找结果通过-
作为参数传递给wc,作为--files0-from
参数:
find . -name '*.vb' -print0 | wc -l --files0-from=-
链接地址: http://www.djcxy.com/p/57163.html
上一篇: Why does the wc utility generate multiple lines with "total"?