考虑一下在https://cloud.r-project.org/src/base/R-3/R-3.4.4.tar.gz中找到的R源代码存储库。我将存储库解压缩到一个文件夹中。现在,我想知道目录中有多少行。因此,我尝试了以下命令:
find . -type f -exec wc -l {} \+这将产生394968,但如果我尝试以下命令:
find . -type f -exec cat {} \+ | wc -l它能产生1848857!
为什么这两个看似相似的find命令操作会产生如此截然不同的结果?另外,找到行数的正确方法是什么,最好是使用命令行实用程序而不是编写一个小工具?
发布于 2018-04-16 18:00:27
您提到的第一个命令find . -type f -exec wc -l {} +实际上是说“在尽可能多的文件上运行wc -l,直到所有文件都被处理”。这可以多次运行wc!
另一方面,find . -type f -exec cat {} + | wc -l可以多次运行cat,但只运行wc一次。(更详细地说,这是因为在本例中,cat是由find调用的,它可以并确实决定运行它的任意次数,而管道字符wc -l之后的部分超出了find的范围,因此只由您的shell运行一次。)
您说第一个命令“产生394968",但实际上并非如此;在我的系统上,它的输出以:
(Many more lines elided...)
23 ./po/Makefile.win
64 ./po/README
1 ./VERSION-NICK
97 ./README
258450 total然而,通过添加grep total,可以看出wc确实运行了两次:
$ find . -type f -exec wc -l {} + | grep total
1590407 total
258450 total实际上,1590407加258450等于1848857,这与第二个命令一致。
对于为什么wc在命令的find -exec wc +版本中多次运行的解释,查找手册页含糊地暗示:
-execcommand{} +
-exec操作的这个变体在选定的文件上运行指定的命令,但是命令行是通过在末尾追加每个选定的文件名来构建的;命令的调用总数将大大少于匹配的文件数。命令行的构建方式与xargs构建其命令行的方式大致相同。
注意这上面写的“远小于.”而不是“只有一次”。xargs文档提示它的选项--max-chars是自动设置的,如果不是用户设置的话:
--max-chars=max-chars-smax-chars
在每个命令行最多使用max-chars字符,包括命令和初始参数以及参数字符串末尾的终止空值。最大允许值与系统相关,计算为exec的参数长度限制,减去环境的大小,减去2048字节的空间。如果此值大于128 this,则使用128 this作为默认值;否则,默认值为最大值。
这限制了一个对wc的单个调用可以传递多少文件名,这就解释了为什么对大量文件将发生几次对wc的调用,每个调用都是在输入的一个分区上操作的。
https://unix.stackexchange.com/questions/438160
复制相似问题