如何使用Windows命令行查找文件中字符串的出现次数?

时间:2012-02-16 07:29:34

标签: windows string file command-line find

我有一个包含电子邮件地址的大文件,我想知道这个文件中有多少个。如何使用Windows命令行执行此操作?

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

findstr /c:"@" mail.txt

9 个答案:

答案 0 :(得分:14)

使用您拥有的内容,您可以通过find管道传输结果。我已经看到过不时使用过的东西。

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

因此,您正在计算由findstr命令生成的行,其中没有垃圾字符串。有点黑客,但它可以为你工作。或者,只需在你关心的字符串上使用find /c即可。最后,你提到了每行一个地址,所以在这种情况下上面的工作,但每行多个地址,这就打破了。

答案 1 :(得分:4)

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

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%

答案 2 :(得分:3)

可能有点晚了,但是下面的脚本对我有效(源文件包含引号字符,这就是我使用'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!

答案 3 :(得分:2)

非常简单的解决方案:

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 将是最佳决策之一。

答案 4 :(得分:1)

我在网上发现了这个。看看它是否有效:

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

答案 5 :(得分:1)

我会在您的系统上安装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/

答案 6 :(得分:1)

好的 - 迟到了,但是......似乎很多受访者都错过了所有电子邮件地址都出现在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/"

在上面的代码片段中,您将先前命令的输出传递给SED,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

...然后只需调用该批处理文件&amp;你的答案会有一个名为“NumFound”的DOS环境变量。

答案 7 :(得分:0)

我就是这样做的,使用带有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%

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

答案 8 :(得分:-1)

使用此:

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