从目标文件夹/文件中提取电子邮件地址的批处理脚本

3

程序:命令提示符(CMD)批处理脚本

我有一个文件夹,里面有很多文件。这些文件中混杂着许多电子邮件地址和其他杂乱的文本内容。我希望能够从每个文件中提取这些电子邮件地址,并创建一个新的文件(.txt),每个地址都尽可能清晰地列出。

我已经花了几个小时找到一个不错的正则表达式“代码”:“[.A-Z-_]@[.A-Z-_]

这个表达式来自于似乎是谷歌可以检测到的唯一关于这个主题的其他论坛帖子 - 这让我感到惊讶。那个帖子可以在这里找到:https://stackoverflow.com/questions/7911482/extract-email-from-text-file-using-batch-job

在那个帖子上,一个名叫Hand-E-Food的人创建了下面的.bat脚本来从选定的文件/文件夹中提取电子邮件地址:

@Echo Off
For /F "tokens=*" %%A In ('FindStr /R /I "[\.A-Z\-_]*@[\.A-Z\-_]*" "results.txt"') Do Call :ExtractEmail "%%A"
Exit /B

:ExtractEmail
Set "Email=%~1"
Set "Email=%Email:*<=%"
Set "Temp=%Email:*>=>%"
Call Set "Email=%%Email:%Temp%=%%"
Echo %Email%>emails.txt
Exit /B

令人惊讶的是,他忽略了对代码进行全面错误测试,遗憾的是它不起作用 - 正如原帖中所提到的那样。令人恼火的是,他从未回应纠正他的错误,现在这个话题已经关闭了。

这就带来了我们这里:一个新话题,询问同样的问题,但2011年本该被回答,却没有得到解决。因此,如果有人能够帮助解决我认为可能是非常有用的简单代码,请借给我们你的专业知识。

P.S. 请不要像Hand-E-Food一样忽略双重检查您的代码是否有效。此外,我在命令提示符方面有一点经验,但是许多查看此线程的用户根本没有任何经验,因此请在代码中使用一些符号来解释 - 至少稍微解释一下正在发生什么。

记住:我们当中没有人知道我们现在知道的一切,只有通过善良的人们向我们充分解释如何做某事,我们才学会了。请充分解释。

谢谢大家,

StepbyStep


"很遗憾它不起作用" -- 你期望得到什么结果,而实际上得到了什么? - Eitan T
基本上,他的批处理脚本的最终结果是创建一个名为“emails.txt”的文件,该文件只有1行输出:“ECHO is off.”。文件的其余部分完全为空白,不包括我知道存在的任何电子邮件地址。我已经通过简单使用代码进行了错误测试:在命令提示符中使用FindStr /R /I "[.A-Z-]*@[.A-Z-]*将导致正确的输出。因此,基本上除了他在:ExtractEmail函数中编写的代码之外,一切都正常工作。预期结果是它列出(最好是在新行上)所有找到的电子邮件地址。 - StepbyStep
1
这不是批处理文件的适当任务,因此提供一些链接。链接的代码仅匹配带有地址的整行,这是您想要的吗?- 行Echo%Email%> emails.txt使用单个>,它将覆盖emails.txt,因此您需要使用Echo%Email%>> emails.txt进行附加ExtractEmail中的代码似乎期望findstr发出由>*<*分隔的单个地址,但事实并非如此,因此该文件为空,因为Call Set“Email =%% Temp%=%%”使%Email%为空,因此Echo%Email%调用没有参数的echo,打印echo is off - Alex K.
谢谢大家的回复。不,输出整行确实很烦人,但我已经想到这将是以后要解决的问题。那么,我假设使用批处理脚本时没有真正的绕过方法了?另外,感谢提供有关如何修复脚本的信息。我现在没有时间,但我相信以后应该能够修复它 - 非常感谢! - StepbyStep
你是否真正使用 findstr 测试过那个针对 FAILURE 的正则表达式?我一直在传递非法的电子邮件地址,例如 @gmail.com,但它仍然让它们通过。 - James K
1个回答

4

好的,这里有一个替代脚本,应该可以胜任:

@echo off
set INPUT_FILE=results.txt
set OUTPUT_FILE=emails.txt
set "REGEXP=[\.A-Z\-_][\.A-Z\-_]*@[\.A-Z\-_][\.A-Z\-_]*"
>nul copy nul %OUTPUT_FILE%
for /f "tokens=*" %%a in (%INPUT_FILE%) do for %%b in (%%a) do (
    for /f %%z in ('echo %%b ^| findstr /R /I "%REGEXP%"') do (
        echo %%z >> %OUTPUT_FILE%
    )
)

很简单:外部循环迭代每行中的以空格分隔的字符串,内部循环使用您的正则表达式过滤电子邮件并将其附加到OUTPUT_FILE
希望这有所帮助!
编辑:我改进了正则表达式以更准确地捕获电子邮件模式。它仍然不完美,但如果您对更好的表达式感兴趣,可以查看此网站

我不知道,让我无法使正则表达式失败的唯一方法是从流中删除@符号。即使这个测试成功:echo bla bla 34ubv::fiddle? @gmail.com?yfyj htfy | findstr /R /I "[\.A-Z\-_]*@[\.A-Z\-_]*"也会将字符串回显。 - James K
我之前使用了OP的正则表达式,并没有多加思考,但现在我对其进行了改进。请查看我的更新答案。不过它还不能处理带有?的电子邮件。 - Eitan T
非常抱歉一直打扰您,但是测试您的新正则表达式对于不正确的域名(例如x@com)仍然失败了。 - James K
我相信这只是一个小问题,但我添加了这个参考网站,它提供了更准确的表达式。 - Eitan T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接