【问题标题】:Count all occurrences of a string in lots of files with grep使用 grep 计算大量文件中字符串的所有出现次数
【发布时间】:2021-09-14 09:11:11
【问题描述】:

我有一堆日志文件。我需要找出一个字符串在所有文件中出现了多少次。

grep -c string *

返回

...
file1:1
file2:0
file3:0
...

使用管道我只能获取出现一次或多次的文件:

grep -c string * | grep -v :0

...
file4:5
file5:1
file6:2
...

我怎样才能只获得组合计数? (如果返回file4:5, file5:1, file6:2,我想返回8。)

【问题讨论】:

  • 你能告诉我 grep -v :0 是做什么的吗? .我知道它对出现次数大于 0 的文件很重要。 -v 选项和 :0 是什么意思?请告诉我。
  • @GauthamHonnavara grep :0 查找与字符串 :0 匹配的行。 -v 是反转该搜索的选项,因此使用 grep -v :0 意味着查找所有不包含 :0 的行,因此具有 file4:5 和 file27:193 的行都将通过,因为它们不包含: 0
  • 您可以使用空格选择多个文件。 grep file1 file2 --options

标签: grep


【解决方案1】:

这适用于每行多次出现:

grep -o string * | wc -l

【讨论】:

  • 这也有效:grep -o string * --exclude-dir=some/dir/one/ --exclude-dir=some/dir/two | wc -l.
  • grep -ioR string * | wc -l 是我用来进行不区分大小写、递归、仅匹配的搜索
  • 这个显示相关文件,然后是匹配总数:grep -rc test . | awk -F: '$NF > 0 {x+=$NF; $NF=""; print} END{print "Total:",x}'
【解决方案2】:
cat * | grep -c string

【讨论】:

  • 这有同样的限制,它只计算一行中的多次出现。不过,我猜这种行为在这种情况下是可以的。
  • @Michael Haren 是的,一行中只能出现一次字符串。
  • 我宁愿做grep -c string<* 所以只是用小于替换空间。
  • 不处理一行中的多次出现
  • 如果您也想在子目录中搜索,这不起作用,而 grep -owc -l 可以。 cat 在像原始问题这样的情况下更快。
【解决方案3】:
grep -oh string * | wc -w

将计算一行中的多次出现

【讨论】:

  • grep -oh "... my that curry was strong" * >> wc :)
【解决方案4】:

不使用 -c,而是将其通过管道传递给 wc -l。

grep string * | wc -l

这将在一行中列出每个出现的事件,然后计算行数。

不过,这会遗漏字符串在一行中出现 2 次以上的情况。

【讨论】:

  • 管道到“wc -l”也可以很好地与“grep -r 'test'”一起使用。它递归地扫描当前目录下所有目录中字符串“test”的所有文件。
【解决方案5】:
cat * | grep -c string

cat 的罕见有用应用之一。

【讨论】:

    【解决方案6】:

    您可以添加-R 以递归搜索(并避免使用cat)和-I 以忽略二进制文件。

    grep -RIc string .
    

    【讨论】:

      【解决方案7】:

      与之前所有答案不同:

      perl -lne '$count++ for m/<pattern>/g;END{print $count}' *
      

      【讨论】:

      • 很高兴看到不使用 grep 的方法,尤其是我的 grep(在 Windows 上)不支持 -o 选项。
      【解决方案8】:

      强制 AWK 解决方案:

      grep -c string * | awk 'BEGIN{FS=":"}{x+=$2}END{print x}'
      

      请注意您的文件名是否包含“:”。

      【讨论】:

        【解决方案9】:

        还处理包含冒号的文件名的 AWK 解决方案:

        grep -c string * | sed -r 's/^.*://' | awk 'BEGIN{}{x+=$1}END{print x}'
        

        请记住,此方法仍然不会在同一行上找到多次出现的string

        【讨论】:

          【解决方案10】:

          如果您想要每个文件的出现次数(例如字符串“tcp”):

          grep -RIci "tcp" . | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr
          

          示例输出:

          53  ./HTTPClient/src/HTTPClient.cpp
          21  ./WiFi/src/WiFiSTA.cpp
          19  ./WiFi/src/ETH.cpp
          13  ./WiFi/src/WiFiAP.cpp
          4   ./WiFi/src/WiFiClient.cpp
          4   ./HTTPClient/src/HTTPClient.h
          3   ./WiFi/src/WiFiGeneric.cpp
          2   ./WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino
          2   ./WiFiClientSecure/src/ssl_client.cpp
          1   ./WiFi/src/WiFiServer.cpp
          

          解释:

          • grep -RIci NEEDLE . - 从当前目录递归查找字符串 NEEDLE(遵循符号链接),忽略二进制文件,计算出现次数,忽略大小写
          • awk ... - 此命令忽略出现次数为零的文件并格式化行
          • sort -hr - 按第一列中的数字倒序排列行

          当然,它也可以与带有选项 -c (count) 的其他 grep 命令一起使用。例如:

          grep -c "tcp" *.txt | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr
          

          【讨论】:

          • 太棒了!像魅力一样工作。节省几天时间。非常感谢。
          【解决方案11】:

          您可以使用简单的grep 来有效捕获出现次数。我将使用-i 选项来确保STRING/StrING/string 被正确捕获。

          给出文件名的命令行:

          grep -oci string * | grep -v :0
          

          如果有一个文件没有出现,则删除文件名并打印 0 的命令行:

          grep -ochi string *
          

          【讨论】:

          • 能否请您详细说明您的答案,添加更多关于您提供的解决方案的描述?
          【解决方案12】:

          递归变体:

          find . -type f -exec cat {} + | grep -c 'string'
          

          【讨论】:

          • 谢谢!只有你的解决方案对我有用(总结了所有文件的匹配项)。
          【解决方案13】:

          我用 grep for windows 测试的仅 Grep 解决方案:

          grep -ro "pattern to find in files" "Directory to recursively search" | grep -c "pattern to find in files"
          

          即使一行中有多个,此解决方案也会计算所有出现次数。 -r 递归搜索目录,-o 将“仅显示与 PATTERN 匹配的行的一部分”——这就是在一行上拆分多个出现并让 grep 在新行上打印每个匹配项;然后使用-c 将这些换行符分隔的结果通过管道传输回grep,以计算使用相同模式的出现次数。

          【讨论】:

            【解决方案14】:

            这是一种比 grep 更快的 AWK 替代方法,它在目录中的 XML 文件集合中处理每行 &lt;url&gt; 的多个匹配项:

            awk '/<url>/{m=gsub("<url>","");total+=m}END{print total}' some_directory/*.xml
            

            这适用于某些 XML 文件没有换行符的情况。

            【讨论】:

              【解决方案15】:

              另一个使用基本命令行函数处理每行多次出现的单行器。

               cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
              

              【讨论】:

                【解决方案16】:
                awk -v RS='' -v FPAT='fast' '{print NF,FILENAME}' <file1..N>
                

                取一个字符串,使其成为一行查找fast的实例,然后打印带有文件名的字段数。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-07-03
                  • 2015-12-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-04-28
                  • 1970-01-01
                  相关资源
                  最近更新 更多