文書化されていない機能を発見しました-FINDSTRは改行文字<CR>
と<LF>
一致し、後続の行で一致を継続できます。ただし、検索文字列はコマンドラインで指定する必要があり、改行文字は変数に含める必要があり、値は遅延展開を介して渡される必要があります。
もう1つの問題は、FORループのIN()句が別の暗黙のCMDセッションで実行され、遅延拡張を再度有効にする必要があることです。また、!2番目の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年1月11日編集
質問を読み直して、間違っていることに気づきました。OPは、例外文字列が前の行に表示されるアイテム番号(検索の後ろを見る)を望んでいましたが、私のソリューションでは、例外が次の行に表示されるアイテム番号のみを見つけることができます(検索を先読み)。
残念ながら、FINDSTRに検索の背後を確認させる方法はありません。
ほとんどの場合、質問に答えないので、上記の答えを削除します。ただし、この回答は、これまで説明されていなかった新しいFINDSTR機能が非常に役立つ可能性があることを示しています。先読み機能は、概念的には後読み機能に十分近いため、それを必要とする人がこの質問から答えを見つける可能性があるため、これを維持する予定です。
XP以降の任意のWindowsマシンで実行される純粋なスクリプトベースのソリューションがありますが、FINDSTRを使用していません。JREPL.BATは、目的のアイテム番号を簡単に抽出できる正規表現コマンドラインです。
jrepl "Item No\. (\d+)\r\n.* Exception: " $1 /m /jmatch /f test.txt