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

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

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

bash 或 vim 会很好!

谢谢

【问题讨论】:

标签: bash vim count grep word


【解决方案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
    

    参考资料:

    【讨论】:

      【解决方案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 的所有 问题中学到了一件事,那就是带有空格的文件名会让你感到困惑。即使文件名中有空格,此脚本也可以工作。

        #!/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 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释,并说明适用的限制和假设。
          猜你喜欢
          • 1970-01-01
          • 2012-02-27
          • 2010-11-24
          • 1970-01-01
          • 2021-02-13
          • 2017-09-03
          • 2014-12-14
          • 2014-03-30
          • 2021-09-09
          相关资源
          最近更新 更多