【发布时间】:2012-03-07 14:37:42
【问题描述】:
我有一个带有电子邮件地址的大文件,我想计算一下这个文件中有多少。如何使用 Windows 的命令行来做到这一点?
我已经尝试过了,但它只是打印匹配的行。 (顺便说一句:所有电子邮件都包含在一行中)
findstr /c:"@" mail.txt
【问题讨论】:
标签: windows string file command-line find
我有一个带有电子邮件地址的大文件,我想计算一下这个文件中有多少。如何使用 Windows 的命令行来做到这一点?
我已经尝试过了,但它只是打印匹配的行。 (顺便说一句:所有电子邮件都包含在一行中)
findstr /c:"@" mail.txt
【问题讨论】:
标签: windows string file command-line find
使用您所拥有的,您可以通过find 传递结果。我经常看到这样的东西。
findstr /c:"@" mail.txt | find /c /v "GarbageStringDefNotInYourResults"
因此,您正在计算 findstr 命令中没有垃圾字符串的行。有点黑客,但它可以为你工作。或者,只需在您关心的字符串上使用find /c。最后,您提到每行一个地址,所以在这种情况下,上述方法有效,但每行多个地址,这会中断。
【讨论】:
为什么不简单地使用它(这决定了包含(至少)@ 字符的行数。):
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%
【讨论】:
非常简单的解决方案:
grep -o "@" mail.txt | grep -c .
记住行尾的点!
这里有一点更容易理解的方式:
grep -o "@" mail.txt | grep -c "@"
第一个 grep 只选择“@”字符串并将每个字符串放在新行上。
第二个 grep 计算行数(或带有 @ 的行数)。
grep 实用程序可以从GnuWin project 或WinGrep 站点安装。它是非常小且安全的文本过滤器。 grep 是最有用的 Unix/Linux 命令之一,我每天都在 Linux 和 Windows 中使用它。 Windows findstr 不错,但没有 grep 之类的功能。
如果您喜欢 CLI 或批处理脚本,在 Windows 中安装 grep 将是最佳选择之一。
【讨论】:
可能有点晚了,但是下面的脚本对我有用(源文件包含引号字符,这就是我使用'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!
【讨论】:
我在网上找到了这个。看看它是否有效:
findstr /R /N "^.*certainString.*$" file.txt | find /c "@"
【讨论】:
findstr /R /N "^.*@.*$" mail.txt | find /c "@" 为我返回 1。也许结果是一行的问题。
FINDSTR: Line 1 is too long.
我会在你的系统上安装 unix 工具(在任何情况下都很方便 :-),然后它真的很简单 - 看看例如这里:
Count the number of occurrences of a string using sed?
(使用 awk:
awk '$1 ~ /title/ {++c} END {print c}' FS=: myFile.txt
)。
您可以在此处获取 Windows unix 工具:
【讨论】:
grep -c -o @ 就足够了(或者grep -o @ | wc -l 如果你有一辆不支持DTRT 的越野车grep)。
awk 脚本计算出现的行数,而不是实际出现的行数。修复起来并不难,但还是更容易使用grep -o。
好的 - 迟到了,但是......似乎许多受访者错过了所有电子邮件地址都出现在 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 行。
最后执行的 = 最重要的。
如果您使用“>”字符将上述所有输出重定向到批处理文件,即:
> CountChars.bat
...然后只需调用该批处理文件,您将获得一个名为“NumFound”的 DOS 环境变量和您的答案。
【讨论】:
我就是这样做的,使用带有 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%
注意:这计算“包含字符串匹配的行数”而不是“文件中的总出现次数”。
【讨论】:
使用这个:
type file.txt | find /i "@" /c
【讨论】: