How can I use findstr with newline regex

I am on a windows dos box. I have a log file that contains a log like:

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 the entire item number that is giving some kind of exception. I use findstr command for this. how can i use newline in my regex? I want all lines that have an Exception word and the next line doesn't.

any help?

+1


source to share


4 answers


I found an undocumented function - FINDSTR CAN matches new string characters <CR>

and <LF>

and will continue matching on subsequent lines. But the search string must be specified on the command line, newline characters must be in variables, and values ​​must be passed with expansion delay.

Another complication is that the IN () clause of the FOR loop is executed in a separate implicit CMD session, and delayed expansion must be re-enabled. Same! characters must be escaped to get through the second CMD session.

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



I just re-read the question and realized I figured it was wrong. The OP wanted the element number where the Exception line appears on the previous line (look for a search), but my solution can only find the element number where the Exception appears on the next line (see search ahead).

Unfortunately, there is no way to make FINDSTR look behind the search.

In most cases I would delete the answer above as it doesn't answer the question. However, this answer does indeed document new FINDSTR functionality that was not described before it could be very useful. The forward look-ahead feature is close enough in concept to mind that someone who needs it can find the answer through this question, so I plan to keep it.

I have a purely script based solution that works on any Windows XP machine, but does not use FINDSTR. JREPL.BAT is a regular expression command line that can easily extract the required item numbers.

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

      

+3


source


I have looked at the findstr documentation and I think it cannot do multi-line searches.

You should probably use more complex tools like awk, or some versions of grep seem to support multi-line regex.



You can look at fooobar.com/questions/39437 / ...

+1


source


If you're on Vista or Windows 7 (or if you're manually installing it on XP), you can use PowerShell to do this:

$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

will then contain a list of all position numbers following the line with Exception

.

0


source


If you can download the tools, you can use the Ruby for Windows command here .

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

      

0


source







All Articles