Findstr - Return 只有正则表达式匹配
Findstr - Return only a regex match
我在文本文件中有这个字符串 (test.txt
):
BLA BLA BLA
BLA BLA
Found 11 errors and 7 warnings
我执行这个命令:
findstr /r "[0-9]+ errors" test.txt
为了得到 11 errors
个字符串。
相反,输出是:
Found 11 errors and 7 warnings
有人可以帮忙吗?
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
请参阅 the Windows PowerShell: Extracting Strings Using Regular Expressions article 了解如何使用上面的脚本。
findstr
总是 return 包含匹配项的每个完整行,它不能仅 returning 子字符串。因此,您需要自己进行子字符串提取。总之,您的 findstr
命令行中存在一些问题,我想指出:
findstr
的字符串参数实际上定义了多个搜索字符串,用白色-space分隔,所以一个搜索字符串是[0-9]+
,另一个是error
.您的文本文件中的 Found 11 errors and 7 warnings
行被 return 编辑,因为 error
只是单词,数字部分不是匹配的一部分,因为 findstr
不支持 +
字符(前一个字符或 class 出现一次或多次),您需要将搜索字符串的那部分更改为 [0-9][0-9]*
才能实现。要将整个字符串视为一个搜索字符串,您需要提供 /C
选项;由于这默认为文字搜索模式,因此您还需要明确添加 /R
选项。
findstr /R /C:"[0-9][0-9]* errors" "test.txt"
然而,改变所有这些也会匹配像 x5 errorse
这样的字符串;为避免这种情况,您可以使用 \<
(单词开头)和 \>
(单词结尾)之类的单词边界。 (或者,您也可以在搜索字符串的两边包含 space,即 /C:" [0-9][0-9]* errors "
,但如果搜索字符串出现在适用行的最开头或结尾,这可能会造成问题。)
所以关于以上所有内容,更正和改进的命令行如下所示:
findstr /R /C:"\<[0-9][0-9]* errors\>" "test.txt"
这将 return 包含匹配项的整行:
Found 11 errors and 7 warnings
如果您只想 return 此类行并排除 2 errors are enough
或 35 warnings but less than 3 errors
等行,您当然可以相应地扩展搜索字符串:
findstr /R /C:"^Found [0-9][0-9]* errors and [0-9][0-9]* warnings$" "test.txt"
无论如何,要提取部分 11 errors
有几种选择:
一个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
也可以使用子字符串替换语法:
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%
我在文本文件中有这个字符串 (test.txt
):
BLA BLA BLA
BLA BLA
Found 11 errors and 7 warnings
我执行这个命令:
findstr /r "[0-9]+ errors" test.txt
为了得到 11 errors
个字符串。
相反,输出是:
Found 11 errors and 7 warnings
有人可以帮忙吗?
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
请参阅 the Windows PowerShell: Extracting Strings Using Regular Expressions article 了解如何使用上面的脚本。
findstr
总是 return 包含匹配项的每个完整行,它不能仅 returning 子字符串。因此,您需要自己进行子字符串提取。总之,您的 findstr
命令行中存在一些问题,我想指出:
findstr
的字符串参数实际上定义了多个搜索字符串,用白色-space分隔,所以一个搜索字符串是[0-9]+
,另一个是error
.您的文本文件中的 Found 11 errors and 7 warnings
行被 return 编辑,因为 error
只是单词,数字部分不是匹配的一部分,因为 findstr
不支持 +
字符(前一个字符或 class 出现一次或多次),您需要将搜索字符串的那部分更改为 [0-9][0-9]*
才能实现。要将整个字符串视为一个搜索字符串,您需要提供 /C
选项;由于这默认为文字搜索模式,因此您还需要明确添加 /R
选项。
findstr /R /C:"[0-9][0-9]* errors" "test.txt"
然而,改变所有这些也会匹配像 x5 errorse
这样的字符串;为避免这种情况,您可以使用 \<
(单词开头)和 \>
(单词结尾)之类的单词边界。 (或者,您也可以在搜索字符串的两边包含 space,即 /C:" [0-9][0-9]* errors "
,但如果搜索字符串出现在适用行的最开头或结尾,这可能会造成问题。)
所以关于以上所有内容,更正和改进的命令行如下所示:
findstr /R /C:"\<[0-9][0-9]* errors\>" "test.txt"
这将 return 包含匹配项的整行:
Found 11 errors and 7 warnings
如果您只想 return 此类行并排除 2 errors are enough
或 35 warnings but less than 3 errors
等行,您当然可以相应地扩展搜索字符串:
findstr /R /C:"^Found [0-9][0-9]* errors and [0-9][0-9]* warnings$" "test.txt"
无论如何,要提取部分 11 errors
有几种选择:
一个
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
也可以使用子字符串替换语法:
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%