windows 如何将 findstr 与换行正则表达式一起使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5631752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 16:37:17  来源:igfitidea点击:

How can I use findstr with newline regular expression

windowsregexdosfindstr

提问by Morin

I'm on windows dos prompt. I have log file which contains log like:

我在 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

I want to extract all the item number who has give some sort of exception. I'm using findstr command for this. how can I use newline in my regular expression? I want to all lines which have Exception word and from next line the item no.

我想提取所有给出某种异常的项目编号。我为此使用 findstr 命令。如何在正则表达式中使用换行符?我想要所有有异常词的行,从下一行开始有项目号。

any help?

有什么帮助吗?

回答by dbenham

I've discovered an undocumented feature - FINDSTR CANmatch new line characters <CR>and <LF>and continue the match on subsequent lines. But the search string must be specified on the command line, the new line characters must be in variables, and the values must be passed via delayed expansion.

我发现了一个未公开的特性- FINDSTR CAN匹配新行字符<CR>,并<LF>和延续到后续行的比赛。但是搜索字符串必须在命令行中指定,换行符必须在变量中,值必须通过延迟扩展传递。

Another complication is the IN() clause of a FOR loop is executed in a separate implicit CMD session, and the delayed expansion must be re-enabled. Also, the ! characters must be escaped so that they make it through to the 2nd CMD session.

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

This little test script does the trick.

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

@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


EDIT 2015-01-11


编辑 2015-01-11

I just reread the question, and realize I got it wrong. The OP wanted the Item Number where the Exception string appears on the prior line (look behind search), but my solution can only find the Item Number where Exception appears on the subsequent line (look ahead search).

我只是重读了这个问题,然后意识到我错了。OP 想要异常字符串出现在前一行的项目编号(向前搜索),但我的解决方案只能找到异常出现在后续行(向前搜索)的项目编号。

Unfortunately, there is no way to get FINDSTR to do a look behind search.

不幸的是,没有办法让 FINDSTR 来查看搜索背后的内容。

Under most circumstances, I would delete the answer above, since it does not answer the question. However, this answer does document a novel FINDSTR functionality that had not been described before that could be very useful. The look ahead feature is close enough in concept to the look behind feature that someone that needs it might find the answer via this question, so I plan to keep it.

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

I do have a purely script based solution that runs on any Windows machine from XP onward, but it does not use FINDSTR. JREPL.BATis a regular expression command line that can easily extract the desired Item Numbers.

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

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

回答by stema

I had a look into the findstr documentationand I think it is not able to do a multiline search.

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

Probably you should use more advanced tools like awk, or some versions of grep seems to support multiline regex too.

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

You can have a look at stackoverflow.com/questions/152708/

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

回答by Tim Pietzcker

If you are on Vista or Windows 7 (or if you install it manually on XP), you can use PowerShell for this:

如果您使用的是 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()
} 

$resultlistwill then contain a list of all item numbers that follow a line with Exceptionin it.

$resultlist然后将包含在其中跟随一行的所有项目编号的列表Exception

回答by kurumi

If you can download tools, here's a Ruby for Windowscommand you can use.

如果您可以下载工具,这里有一个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