2

私は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コマンドを使用しています。正規表現で改行を使用するにはどうすればよいですか?例外ワードがあるすべての行に、次の行からアイテム番号を指定します。

何か助けはありますか?

4

5 に答える 5

5

文書化されていない機能を発見しました-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
于 2012-01-07T22:09:36.987 に答える
1

findstrのドキュメントを調べましたが、複数行の検索はできないと思います。

おそらく、awkのようなより高度なツールを使用する必要があります。そうでない場合、grepの一部のバージョンは複数行の正規表現もサポートしているようです。

あなたはstackoverflow.com/questions/152708/を見ることができます

于 2011-04-12T07:59:39.507 に答える
0

肯定的な後読みを使用した別の PowerShell の例:

'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
Timestamp: Exception: OutOfRangeException
Timestamp: Message: Inventory Item is not stock. Item No. 23424' | 
  set-content input.txt

get-content -raw input.txt | 
  select-string -allmatches '((?<=exception.*\n.*)\d+)' | 
  % matches | % value
23423
23424
于 2021-09-01T23:23:53.843 に答える
-1

VistaまたはWindows7を使用している場合(または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

于 2011-04-12T08:37:48.913 に答える
-2

ツールをダウンロードできる場合は、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
于 2011-04-12T08:52:51.040 に答える