如何递归计算目录中的单词数?

Posted

技术标签:

【中文标题】如何递归计算目录中的单词数?【英文标题】:How can I count the number of words in a directory recursively? 【发布时间】:2016-06-04 05:36:53 【问题描述】:

我正在尝试计算项目中编写的字数。文件夹有几级,里面有很多文本文件。

谁能帮我找到一个快速的方法来做到这一点?

bash 或 vim 会很好!

谢谢

【问题讨论】:

如何判断一个文件是否为文本文件?通用扩展? How to count all the lines of code in a directory recursively?的可能重复 【参考方案1】:

使用find 扫描目录树,然后wc 将完成剩下的工作

$ find path -type f | xargs wc -w | tail -1

最后一行给出总数。

【讨论】:

【参考方案2】:

tldr;

$ find . -type f -exec wc -w  + | awk '/total/print $1' | paste -sd+ | bc

解释:

find . -type f -exec wc -w + 将对.(当前工作目录)包含的所有文件(递归)运行wc -wfind 将尽可能少地执行wc但尽可能多地以遵守ARG_MAX --- 系统命令长度限制。当文件数量(和/或其组成长度)超过 ARG_MAX 时,find 会多次调用 wc -w,给出多个 total 行:

$ find . -type f -exec wc -w  + | awk '/total/print $0'
  8264577 total
  654892 total
 1109527 total
 149522 total
 174922 total
 181897 total
 1229726 total
 2305504 total
 1196390 total
 5509702 total
  9886665 total

通过仅打印每个 total 行的第一个空格分隔字段来隔离这些部分和:

$ find . -type f -exec wc -w  + | awk '/total/print $1'
8264577
654892
1109527
149522
174922
181897
1229726
2305504
1196390
5509702
9886665

paste 带有+ 分隔符的部分总和以给出中缀总和:

$ find . -type f -exec wc -w  + | awk '/total/print $1' | paste -sd+
8264577+654892+1109527+149522+174922+181897+1229726+2305504+1196390+5509702+9886665

使用bc 计算中缀求和,它同时支持中缀表达式和任意精度:

$ find . -type f -exec wc -w  + | awk '/total/print $1' | paste -sd+ | bc
30663324

参考资料:

https://www.cyberciti.biz/faq/argument-list-too-long-error-solution/ https://www.in-ulm.de/~mascheck/various/argmax/ https://linux.die.net/man/1/find https://linux.die.net/man/1/wc https://linux.die.net/man/1/awk https://linux.die.net/man/1/paste https://linux.die.net/man/1/bc

【讨论】:

【参考方案3】:

您可以找到所有内容并将其打印到wc

find path -type f -exec cat  \; -exec echo \; | wc -w

注意:如果文件不以换行符结尾,则需要-exec echo \;,在这种情况下,一个文件的最后一个单词和下一个文件的第一个单词不会分开。

或者您可以找到 wc 并使用 awk 来汇总计数:

find . -type f -exec wc -w  \; | awk ' sum += $1  END  print sum '

【讨论】:

【参考方案4】:

如果我从关于 SO 的所有bash 问题中学到了一件事,那就是带有空格的文件名会让你感到困惑。即使文件名中有空格,此脚本也可以工作。

#!/usr/bin/env bash

shopt -s globstar
count=0
for f in **/*.txt
do
    words=$(wc -w "$f" | awk 'print $1')
    count=$(($count + $words))
done
echo $count

【讨论】:

【参考方案5】:

假设你不需要递归计算单词并且你想包含当前目录中的所有文件,你可以使用一个简单的方法,例如:

wc -l *


10  000292_0
500 000297_0
510 total

如果您只想计算当前目录中特定扩展名的字数,您可以尝试:

cat *.txt | wc -l

【讨论】:

这个答案不处理多个子目录(即没有递归),它假设文件夹中的每个文件都是一个文本文件。 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释,并说明适用的限制和假设。

以上是关于如何递归计算目录中的单词数?的主要内容,如果未能解决你的问题,请参考以下文章

sh 计算目录中的文件数(递归)

python-027-递归-求序列最大值、计算第n个调和数、转换字符到整数

打印 C 中的递归数

递归(计算组合数判断回文字符串汉诺塔问题)

如何有效地计算mathematica中的递归关系?

用递归函数计算从n个人中选择k个人组成一个委员会的不同组合数