使用 wc 递归计算行数时结果错误

使用 wc 递归计算行数时结果错误

我使用以下 Linux 命令来递归计算文件夹结构中文本文件的行数:

find . -name '*.txt' | xargs -d '\n' wc -l

这将输出所有找到的文件及其行数:

  86 ./folder1/folder11/folder111/file1.txt
  67 ./folder1/folder11/folder112/file2.txt
7665 ./folder1/folder11/folder113/file3.txt
..., etc.
1738958 total

总共有 24k+ 个文件。每个文件的行数都是正确的,并且所有文件都已拥有。但总行数不正确。即使对于这种结构的子文件夹,总行数也要大得多。例如:

cd folder1/folder11
find . -name '*.txt' | xargs -d '\n' wc -l

最后给出 23M 行:

22535346 total

所有行的总数应> 100M,而不是1.7M。我在这里缺少什么?

答案1

如果您有 GNU wc,请使用

find . -name "*.txt" -print0 | wc -l --files0-from -

此选项的手册部分解释了为什么你所做的事情不起作用:

‘--files0-from=file’

禁止处理命令行上指定的文件,而是处理文件中指定的文件文件;每个名称均以零字节 (ASCII NUL) 结尾。当文件名列表太长以至于可能超出命令行长度限制时,这非常有用。在这种情况下,运行wcviaxargs是不可取的,因为它将列表分成几部分,并wc为每个子列表而不是整个列表打印总计。生成 ASCII NUL 终止文件名列表的一种方法是使用 GNU find,使用其-print0谓词。如果文件为“-”,则从标准输入读取 ASCII NUL 终止的文件名。

如果您wc不支持此选项,您可以通过一个简单的脚本发送输出,以提取所有“总”行并将它们相加。

... | awk '$2=="total"{t=t+$1} END{print t " total"}'

答案2

由于您有如此多的文件,我认为正在发生的事情是wc -lxargs.这本质上就是xargs目的;一次对所有文件进行一次调用wc -l将不起作用,因为该命令太大。您看到的结果是最后一批。如果向上滚动几千行左右,您最终将看到上一批的结果。

如果您只是在计算所有文件中的总行数,则可以将cat它们全部删除并将该数据发送到wc -l

find . -type f -name '*.txt' -exec cat {} + | wc -l

这将cat在批量找到的文件上执行,然后将生成的数据流传递到wc -l.

相关内容