Findstr - 仅返回正则表达式匹配项

11

我有一个文本文件(test.txt),其中包含以下字符串:

BLA BLA BLA
BLA BLA
Found 11 errors and 7 warnings

我执行这个命令:

findstr /r "[0-9]+ errors" test.txt

为了获得仅有的 11个错误 字符串。

然而,输出结果是:

Found 11 errors and 7 warnings

有人可以帮忙吗?


你正在使用错误的函数。了解一下findstr及其功能。 - malutki5200
3个回答

10
findstr 始终返回包含匹配的完整行,无法仅返回子字符串。因此,您需要自己进行子字符串提取。无论如何,您的 findstr 命令行存在一些问题,我想指出:

findstr 的字符串参数实际上定义了由空格分隔的多个搜索字符串,因此一个搜索字符串是 [0-9]+,另一个是 error。您文本文件中的 Found 11 errors and 7 warnings 行是由于仅有单词 error 而返回的,数字部分不属于匹配的一部分,因为 findstr 不支持 + 字符(前面字符或类的一个或多个出现),您需要将搜索字符串的那部分更改为 [0-9][0-9]* 才能实现匹配。要将整个字符串视为一个搜索字符串,您需要提供 /C 选项;由于这默认为字面搜索模式,您还需要显式添加 /R 选项。

findstr /R /C:"[0-9][0-9]* errors" "test.txt"

但这样更改还会匹配到类似于x5 errorse的字符串;为了避免这种情况,您可以使用单词边界符,如\<(单词开头)和\>(单词结尾)。 (或者您也可以在搜索字符串两侧包含一个空格,例如/C:" [0-9][0-9]* errors ",但如果搜索字符串出现在适用行的开头或结尾,这可能会导致问题。)

因此,针对上述所有内容,已更正和改进的命令行如下:

findstr /R /C:"\<[0-9][0-9]* errors\>" "test.txt"

这将返回包含匹配内容的整行:

Found 11 errors and 7 warnings
如果你只想返回这样的行,并排除像“2个错误已经足够”或“35个警告但少于3个错误”的行,当然可以相应地扩展搜索字符串:
findstr /R /C:"^Found [0-9][0-9]* errors and [0-9][0-9]* warnings$" "test.txt"

无论如何,要提取11 errors这部分,有几种选择:

  1. 使用for /F循环可以解析findstr的输出并提取特定的标记:

    for /F "tokens=2-3 delims= " %%E in ('
        findstr/R /C:"\<[0-9][0-9]* errors\>" "test.txt"
    ') do echo(%%E %%F
    
  2. 子字符串替换语法也可以使用:

  3. for /F "delims=" %%L in ('
        findstr /R /C:"\<[0-9][0-9]* errors\>" "test.txt"
    ') do set "LINE=%%L"
    set "LINE=%LINE:* =%"
    set "LINE=%LINE: and =" & rem "%"
    echo(%LINE%
    

7
< p > findstr 工具无法仅提取匹配项。使用 Powershell 更容易实现此目的。

这里有一个例子:

$input_path = 'c:\ps\in.txt'
$output_file = 'c:\ps\out.txt'
$regex = '[0-9]+ errors'
select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file

请参阅Windows PowerShell:使用正则表达式提取字符串文章,了解如何使用上述脚本。


有没有其他的命令行工具可以完成这个任务?我不想使用PowerShell。 - ohadinho
1
在Windows上?嗯,支持真正的正则表达式的选项并不多。PowerShell是一个内置软件,为什么不使用它呢?如果您坚持要用其他的解决方案,那么VBScript怎么样? - Wiktor Stribiżew
在PS中可能会更容易,但在“非PowerShell”中该怎么做呢?如果findstr无法单独完成此操作,那么可以使用哪个命令? - Mike 'Pomax' Kamermans
@Mike'Pomax'Kamermans 有任何可以提取正则表达式匹配的工具。PS 不是唯一的选择,但它似乎是最方便的,因为它随 Windows 一起发货。 - Wiktor Stribiżew
除非有其他部分可以添加,否则似乎没有什么可以添加到findstr使其工作。在这种情况下,不是“使用PowerShell更容易”,而是“你必须使用PowerShell或其他具有真正正则表达式功能的工具”? - Mike 'Pomax' Kamermans

1

可以使用Type(或Cat)和Grep来实现。

这将允许随机数量的错误(最多四位数字)。
type c:\temp\test.txt | grep -Eo '[0-9]{1,4} errors'
11 errors

如果错误数字大于四位数,请修改上述内容以适应预期的最大位数。

对于一个精确的区分大小写选项
type c:\temp\test.txt | grep -o "11 errors"
11 errors

或者使用此不区分大小写的选项Cat
cat c:\temp\test.txt | grep -o -i "11 ERRORS"
11 errors


1
问题是关于cmd(Windows命令行),它不支持grepcat(本地)。 - Stephan

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