【问题标题】:How to find the number of occurrences of a string in file using windows command line?如何使用 Windows 命令行查找文件中字符串的出现次数?
【发布时间】:2012-03-07 14:37:42
【问题描述】:

我有一个带有电子邮件地址的大文件,我想计算一下这个文件中有多少。如何使用 Windows 的命令行来做到这一点?

我已经尝试过了,但它只是打印匹配的行。 (顺便说一句:所有电子邮件都包含在一行中)

findstr /c:"@" mail.txt

【问题讨论】:

    标签: windows string file command-line find


    【解决方案1】:

    使用您所拥有的,您可以通过find 传递结果。我经常看到这样的东西。

    findstr /c:"@" mail.txt | find /c /v "GarbageStringDefNotInYourResults"
    

    因此,您正在计算 findstr 命令中没有垃圾字符串的行。有点黑客,但它可以为你工作。或者,只需在您关心的字符串上使用find /c。最后,您提到每行一个地址,所以在这种情况下,上述方法有效,但每行多个地址,这会中断。

    【讨论】:

    • @Patryk,我的错误,我误读了所有电子邮件都在各自的行中。将修改。
    【解决方案2】:

    为什么不简单地使用它(这决定了包含(至少)@ 字符的行数。):

    find /C "@" "mail.txt"
    

    示例输出:

    ---------- MAIL.TXT: 96
    

    要避免输出中的文件名,请将其更改为:

    find /C "@" < "mail.txt"
    

    示例输出:

    96
    

    要捕获结果数字并将其存储在变量中,请使用此(在批处理文件中将 %N 更改为 %%N):

    set "NUM=0"
    for /F %N in ('find /C "@" ^< "mail.txt"') do set "NUM=%N"
    echo %NUM%
    

    【讨论】:

      【解决方案3】:

      非常简单的解决方案:

      grep -o "@" mail.txt | grep -c .
      

      记住行尾的点!

      这里有一点更容易理解的方式:

      grep -o "@" mail.txt | grep -c "@"
      

      第一个 grep 只选择“@”字符串并将每个字符串放在新行上。

      第二个 grep 计算行数(或带有 @ 的行数)。

      grep 实用程序可以从GnuWin projectWinGrep 站点安装。它是非常小且安全的文本过滤器。 grep 是最有用的 Unix/Linux 命令之一,我每天都在 Linux 和 Windows 中使用它。 Windows findstr 不错,但没有 grep 之类的功能。

      如果您喜欢 CLI 或批处理脚本,在 Windows 中安装 grep 将是最佳选择之一。

      【讨论】:

      • 'grep' 不是内部或外部命令、可运行程序或批处理文件。
      【解决方案4】:

      可能有点晚了,但是下面的脚本对我有用(源文件包含引号字符,这就是我使用'usebackq'参数的原因)。 插入符号 (^) 在 Windows 批处理脚本语言中充当转义字符。

      @setlocal enableextensions enabledelayedexpansion    
      SET TOTAL=0
      FOR /F "usebackq tokens=*" %%I IN (file.txt) do (
          SET LN=%%I
          FOR %%J IN ("!LN!") do (
              FOR /F %%K IN ('ECHO %%J ^| FIND /I /C "searchPhrase"') DO (
                  @SET /A TOTAL=!TOTAL!+%%K
              )
          )
      )
      ECHO Number of occurences is !TOTAL!
      

      【讨论】:

        【解决方案5】:

        我在网上找到了这个。看看它是否有效:

        findstr /R /N "^.*certainString.*$" file.txt | find /c "@"
        

        【讨论】:

        • 谢谢你,但findstr /R /N "^.*@.*$" mail.txt | find /c "@" 为我返回 1。也许结果是一行的问题。
        • 我认为这可行,但我的文本不仅仅是一行,而是一个 200KB 的 JSON,所以我得到了FINDSTR: Line 1 is too long.
        【解决方案6】:

        我会在你的系统上安装 unix 工具(在任何情况下都很方便 :-),然后它真的很简单 - 看看例如这里:

        Count the number of occurrences of a string using sed?

        (使用 awk:

        awk '$1 ~ /title/ {++c} END {print c}' FS=: myFile.txt
        

        )。

        您可以在此处获取 Windows unix 工具:

        http://unxutils.sourceforge.net/

        【讨论】:

        • 只要grep -c -o @ 就足够了(或者grep -o @ | wc -l 如果你有一辆不支持DTRT 的越野车grep)。
        • 另外,awk 脚​​本计算出现的行数,而不是实际出现的行数。修复起来并不难,但还是更容易使用grep -o
        • @tripleee 我知道我可以使用 unix 工具(这更容易使用),但我想使用 Windows 的命令行。
        • 给你更多的权力,然后,或者实际上,更少。 (^:
        【解决方案7】:

        好的 - 迟到了,但是......似乎许多受访者错过了所有电子邮件地址都出现在 1 行的原始规范。这意味着除非您在每次出现 @ 符号时都引入 CRLF,否则您对使用 FINDSTR /c 变体的建议将无济于事。

        在用于 DOS 的 Unix 工具中,功能非常强大的 SED.exe。去谷歌上查询。它震撼了 RegEx。这是一个建议:

        find "@" datafile.txt | find "@" | sed "s/@/@\n/g" | find /n "@" | SED "s/\[\(.*\)\].*/Set \/a NumFound=\1/">CountChars.bat
        

        说明:(假设包含数据的文件名为“Datafile.txt”) 1) 第一个 FIND 包含 3 行标题信息,这会引发行数方法,因此将结果通过管道传输到第二个(相同)查找以去除不需要的标题信息。

        2) 将上述结果通过管道传送到 SED,SED 将搜索每个“@”字符并将其替换为自身+“\n”(这是一个“新行”,又名 CRLF),它会在其上获取每个“@”输出流中自己的行...

        3) 当您将上述 SED 输出通过管道传输到 FIND /n 命令时,您将在每行的开头添加行号。现在,您所要做的就是隔离每一行的数字部分并在其前面加上“SET /a”,以将每一行转换为一个批处理语句,该语句(随着每一行增加)将变量设置为等于该行的编号。

        4) 隔离每一行的数字部分,并按照上述通过:
        | SED "s/\[\(.*\)\].*/Set \/a NumFound=\1/"

        在上面的 sn-p 中,您将前面命令的输出通过管道传输到 SED,它使用此语法“s/WhatToLookFor/WhatToReplaceItWith/”来执行以下步骤:

        a) 查找“[”(必须以“\”开头来“转义”)

        b) 开始保存(或“标记化”)接下来的内容,直到结束“]”

            --> in other words it ignores the brackets but stores the number
            --> the ".*" that follows the bracket wildcards whatever follows the "]"
        

        c) \(\) 之间的内容是“标记化的”,这意味着稍后可以在“WhatToReplaceItWith”部分中引用它。标记化的第一个内容通过“\1”引用,然后通过“\2”引用,等等。

        所以...我们忽略了 [ 和文字字符串: Set /a NumFound= + 已保存或“标记化”的数字,即 ...第一行将显示:Set /a NumFound=1 ...& 下一行显示:Set /a NumFound=2 等等等等。

        因此,如果您有 1,283 个电子邮件地址,那么您的结果将有 1,283 行。

        最后执行的 = 最重要的。

        如果您使用“>”字符将上述所有输出重定向到批处理文件,即: &gt; CountChars.bat

        ...然后只需调用该批处理文件,您将获得一个名为“NumFound”的 DOS 环境变量和您的答案。

        【讨论】:

          【解决方案8】:

          我就是这样做的,使用带有 FINDSTR 的 AND 条件(计算日志文件中的错误数):

          SET COUNT=0
          FOR /F "tokens=4*" %%a IN ('TYPE "soapui.log" ^| FINDSTR.exe /I /R^
           /C:"Assertion" ^| FINDSTR.exe /I /R /C:"has status VALID"') DO (
            :: counts number of lines containing both "Assertion" and "has status VALID"
            SET /A COUNT+=1
          )
          SET /A PASSNUM=%COUNT%
          

          注意:这计算“包含字符串匹配的行数”而不是“文件中的总出现次数”。

          【讨论】:

            【解决方案9】:

            使用这个:

            type file.txt | find /i "@" /c
            

            【讨论】:

            • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
            猜你喜欢
            • 2013-07-10
            • 2017-04-16
            • 1970-01-01
            • 1970-01-01
            • 2010-09-22
            • 2012-12-26
            • 1970-01-01
            • 2013-08-25
            相关资源
            最近更新 更多