如何使用新行正则expression式使用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命令。 我怎样才能在我的正则expression式中使用换行符? 我想所有的行有exception字,从下一行的项目号。

任何帮助?

我发现了一个未公开的功能 – 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要求在前一行出现异常字符串的项目编号(看后面的搜索),但是我的解决方案只能找到后续行中出现异常的项目编号(向前搜索)。

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

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

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

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

我看了一下findstr文档 ,我认为它不能做多行搜索。

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

你可以看看stackoverflow.com/questions/152708/

如果您使用的是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中的一行。

如果您可以下载工具,可以使用下面的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