如何将findstr与newline正则表达式一起使用

时间:2011-04-12 07:21:54

标签: windows regex dos findstr

我正在使用Windows dos提示符。我有包含日志的日志文件:

Timestamp: Order received for Item No. 26551
Timestamp: Exception: OutOfRangeException
Timestamp: Message: Inventory Item is not stock. Item No. 23423
Timestamp: Order received for Item No. 23341

我想提取所有提供某种异常的商品编号。我正在使用findstr命令。如何在正则表达式中使用换行符?我希望所有包含Exception单词的行和下一行的项目编号

任何帮助?

4 个答案:

答案 0 :(得分:4)

我发现了一个未记录的功能 - FINDSTR CAN 匹配换行符<CR><LF>并继续匹配后续行。但必须在命令行中指定搜索字符串,新行字符必须在变量中,并且必须通过延迟扩展传递值。

另一个复杂因素是FOR循环的IN()子句在单独的隐式CMD会话中执行,并且必须重新启用延迟扩展。还有!必须转义字符,以便它们进入第二个CMD会话。

这个小小的测试脚本可以解决问题。

@echo off
setlocal enableDelayedExpansion
if "%~1"==":doSearch" goto :doSearch

::Define a variable as a LineFeed (0x0A) character
set LF=^


:: The above 2 blank lines MUST be preserved!

::Define a CR variable as a CarriageReturn (0x0D) character
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"

set file="test.txt"
for /f "delims=" %%A in ('cmd /v:on /c^"findstr /rc:"Item No\. .*^!CR^!*^!LF^!.* Exception: " %file%^"') do (
  set "ln=%%A"
  set "item=!ln:*Item No. =!"
  echo Item No. !item! had an exception
)
exit /b


编辑2015-01-11

我只是重读了这个问题,并意识到我弄错了。 OP需要项目编号,其中Exception字符串出现在前一行(查看搜索后面),但我的解决方案只能找到项目编号,其中Exception出现在后续行(向前搜索)。

不幸的是,没有办法让FINDSTR看一下搜索。

在大多数情况下,我会删除上面的答案,因为它没有回答这个问题。但是,这个答案确实记录了一个新的FINDSTR功能,这个功能以前没有描述过,可能非常有用。前瞻功能在概念上足够接近后面的功能,需要它的人可能会通过这个问题找到答案,所以我打算保留它。

我确实有一个纯粹的基于脚本的解决方案,可以在XP以后的任何Windows机器上运行,但它不使用FINDSTR。 JREPL.BAT是一个正则表达式命令行,可以轻松提取所需的项目编号。

jrepl "Item No\. (\d+)\r\n.* Exception: " $1 /m /jmatch /f test.txt

答案 1 :(得分:1)

我查看了findstr documentation,我认为它无法进行多行搜索。

可能你应该使用更高级的工具,比如awk,或者某些版本的grep似乎也支持多行正则表达式。

您可以查看stackoverflow.com/questions/152708/

答案 2 :(得分:-1)

如果您使用的是Vista或Windows 7(或者在XP上手动安装),可以使用PowerShell:

$resultlist = new-object System.Collections.Specialized.StringCollection
$regex = [regex] '(?m)^.*Exception.*\r\n.*Item No\. (\d+)'
$match = $regex.Match($subject)
while ($match.Success) {
    $resultlist.Add($match.Groups[1].Value) | out-null
    $match = $match.NextMatch()
} 
然后,

$resultlist将包含其中包含Exception行的所有项目编号的列表。

答案 3 :(得分:-1)

如果您可以下载工具,可以使用Ruby for Windows命令。

C:\work>ruby -ne "print gets.split.last if /Exception/" file
23423
C:\work>type file
Timestamp: Order received for Item No. 26551
Timestamp: Exception: OutOfRangeException
Timestamp: Message: Inventory Item is not stock. Item No. 23423
Timestamp: Order received for Item No. 23341

C:\work>ruby -ne "print gets.split.last if /Exception/" file
23423