我使用以下 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) 结尾。当文件名列表太长以至于可能超出命令行长度限制时,这非常有用。在这种情况下,运行
wc
viaxargs
是不可取的,因为它将列表分成几部分,并wc
为每个子列表而不是整个列表打印总计。生成 ASCII NUL 终止文件名列表的一种方法是使用 GNUfind
,使用其-print0
谓词。如果文件为“-”,则从标准输入读取 ASCII NUL 终止的文件名。
如果您wc
不支持此选项,您可以通过一个简单的脚本发送输出,以提取所有“总”行并将它们相加。
... | awk '$2=="total"{t=t+$1} END{print t " total"}'
答案2
由于您有如此多的文件,我认为正在发生的事情是wc -l
由xargs
.这本质上就是xargs
目的;一次对所有文件进行一次调用wc -l
将不起作用,因为该命令太大。您看到的结果是最后一批。如果向上滚动几千行左右,您最终将看到上一批的结果。
如果您只是在计算所有文件中的总行数,则可以将cat
它们全部删除并将该数据发送到wc -l
:
find . -type f -name '*.txt' -exec cat {} + | wc -l
这将cat
在批量找到的文件上执行,然后将生成的数据流传递到wc -l
.