0

I am trying to find a command or batch file that can find specific text in a line of a log file. When the text is found, I want to include the previous 3 lines before the text that is found. I saw some examples using a FOR loop but I can only get one token and not the previous lines. Is there a way to do this without utilities in a batch file?

@echo off

svn log https://sub.mycompany.com/svn/company-dev/ > c:\temp\svn.txt
setlocal EnableDelayedExpansion
rem Assemble the list of line numbers
set JiraID=%1
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"%JiraID%" c:\temp\svn.txt') 
do (             
set /A beforeo=%%a, before=%%a-1, before2=%%a-2
set "numbers=!numbers!: !beforeo!: !before!: !before2!:"
)
rem Search for the lines
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" c:\temp\svn.txt ^|   
findstr /B "%numbers%"') do echo %%b)           
del c:\temp\svn.txt

I actually do not want to dump the SVN log if there is a way to do it inline with SVN LOG command. The file created has spaces when outputed to text,

The output being read has spaces between lines as well and the output sometimes does not include the "-----" lines so it was tricky trying to collect the correct lines. Any ideas?

------------------------------------------------------------------------
r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines

Removed unused "Calculated Fields" column entry.
Jira ID: JIRA-977

------------------------------------------------------------------------
Mark
  • 3,609
  • 1
  • 22
  • 33
Gary Seven
  • 109
  • 1
  • 1
  • 7

2 Answers2

2

No need for a FOR /F loop. FINDSTR has an undocumented ability to search across line breaks, so a single FINDSTR command can do it! See What are the undocumented features and limitations of the Windows FINDSTR command? for more info.

@echo off
setlocal enableDelayedExpansion

:: Define LF to contain a line feed character (0x0A)
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE

:: Define CR to contain a carriage return character (0x0D)
for /f %%A in ('copy /Z "%~dpf0" nul') do set "CR=%%A"

:: Define the string to search for
set "s=something"

findstr /r /c:"!s!" /c:"!lf!.*!s!" /c:"!lf!.*!cr!*!lf!.*!s!" /c:"!lf!.*!cr!*!lf!.*!cr!*!lf!.*!s!" test.txt

Since the above search uses a regular expression, any meta-characters in the search string must be escaped. For example, a period in the search string would be represented as \.


Update in response to edited question

It is not necessary to save the original file to a temp file - it can be piped directly into FINDSTR.

@echo off
setlocal enableDelayedExpansion

:: Define LF to contain a line feed character (0x0A)
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE

:: Define CR to contain a carriage return character (0x0D)
for /f %%A in ('copy /Z "%~dpf0" nul') do set "CR=%%A"

:: Define the string to search for
set "s=%~1"

svn log https://sub.mycompany.com/svn/company-dev/|findstr /ri /c:"!s!" /c:"!lf!.*!s!" /c:"!lf!.*!cr!*!lf!.*!s!" /c:"!lf!.*!cr!*!lf!.*!cr!*!lf!.*!s!"
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • @user3609755 - Not much change needed, though I am a bit confused how many lines of output you want. Your description describes 3 lines before the found line, plus the found line. But your code tries to get 2 lines plus the found line. My answer returns the 3 prior lines, plus the found line. – dbenham May 06 '14 at 21:55
  • Due to the file sometimes it can be 3 lines or 2 depending on how the change was committed to Subversion and as i metioned "------" line breaks. Subversion output is not standard so there maybe spaces – Gary Seven May 06 '14 at 22:57
  • I ran the script and it gave me the data i needed . Thanks – Gary Seven May 06 '14 at 23:04
  • One more question. Is there a way to modify the file so that it shows all text between the lines "----------------" if the text is found? That way if it finds the text it will give all 3 lines of the update regardless if its before or after the text. Subversion updates the log with before/after lines "-----------" so we need all text associated with the revision usually 3 lines. – Gary Seven May 07 '14 at 19:22
  • @user3609755 - That sounds like an entirely different (new) question. – dbenham May 07 '14 at 19:29
  • Ok i opened a new question – Gary Seven May 07 '14 at 20:08
0

(Answer before question was edited)

This might be what you're looking for:

@echo off
setlocal enabledelayedexpansion
set l1=
set l2=
set l3=
set findme=test
for /f %%l in (t.txt) do (
    if "%%l"=="%findme%" echo.!l1! & echo.!l2! & echo.!l3!
    set l1=!l2!
    set l2=!l3!
    set l3=%%l
    )

Set findme to the value you want.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222