我发现了一个未记录的功能 - FINDSTR 可以匹配换行符<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