Search code examples
batch-filecmdfindfindstr

Batch file to extract text from file


I have a log file I am attempting to extract particular lines from. When I crop the file to a few lines above and below I am able to get it. However, there is multiple instances of what I am trying to find preventing using the FULL file.

Following is some code I have tried...

 for /f "tokens=1* delims=[]" %%a in ('find /n "    <Line Text="***********TEST1  TEST  TEST************" />" ^< TEST.LOG') do (set H=%%a
 )

 for /f "tokens=1* delims=[]" %%a in ('find /n "</Report>" ^< TEST.LOG') do (
 set T=%%a
 )

 for /f "tokens=1* delims=[]" %%a in ('find /n /v "" ^< TEST.LOG') do (
 if %%a GEQ !H! if %%a LEQ !T! echo.%%b
 )>> newfile.txt

I am hoping to get the following:

 <Line Text="***********TEST1  TEST  TEST************" />
 ~ALL LINES IN BETWEEN~
 </Report>

Solution

  • Updated:

    You want to find <Line Text="***********TEST1 TEST TEST************" /> then print it and any line until the First </Report> is encountered, then look for the next <Line Text="***********TEST1 TEST TEST************" /> and print it and every following line until the next </Report> for every time it occurs throughout?

    – Ben Personick 1 hour ago

    OR do you just want to take from the first <Line Text="***********TEST1 TEST TEST************" /> to the first </Report>?

    – Ben Personick 1 hour ago

    Find <Line Text="***********TEST1 TEST TEST************" /> then print it and any line until the First </Report> is encountered, then look fo rthe next <Line Text="***********TEST1 TEST TEST************" /> and print it and every followinng line until the next </Report> for every time it occurs. I feel there should ONLY be 1 sequence, however, at times this situation could very well be possible. Thanks for asking, very solid question!

    – T-Diddy 1 hour ago

    Okay, this should work the way you expect then, however, if there are a lot of unexpected characters it might make more sense to amend how the lines are being outputted to use SET instead of echo.

    @(setlocal
      ECHO OFF
      SET "_LogFile=C:\Admin\TestLog.log"
      SET "_ResultFile=C:\Admin\TestLog.txt"
      SET "_MatchString_Begin=<Line Text="***********AAAAA BBBB CCCC************" />"
      SET "_MatchString_End=</Report>"
      SET "_Line#_Begin="
    )
    
    CALL :Main
    
    ( ENDLOCAL
      EXIT/B
    )
    :Main
      IF EXIST "%_ResultFile%" (
        DEL /F /Q "%_ResultFile%"
      )
      ECHO.&ECHO.== Processing ==&ECHO.
      FOR /F "Delims=[]" %%# IN ('
        Find /N "%_MatchString_Begin:"=""%" "%_LogFile%" ^| FIND "["
      ') DO (
        ECHO. Found Match On Line %%#
        SET /A "_Line#_Begin=%%#-1"
        CALL :Output
      )
      ECHO.&ECHO.== Completed ==&ECHO.&ECHO.Results to Screen will Start in 5 Seconds:
      timeout 5
      Type "%_ResultFile%"
    GOTO :EOF
    
    :Output
      FOR /F "SKIP=%_Line#_Begin% Tokens=* usebackq" %%_ IN (
        "%_LogFile%"
      ) DO (
        ECHO(%%_
        ECHO("%%_" | FIND /I "%_MatchString_End%" >NUL&&(
          GOTO :EOF
        )
      )>>"%_ResultFile%"
    GOTO :EOF
    

    Original Response Only Shows First Matched Content, based on this Comment:

    This works great with my "cropped" file. However, in the ORIGINAL, ONLY unique line I have is <Line Text="***********AAAAA BBBB CCCC************" />. I can't seem to be able to use the full line as my batch just exits out, but am able to input "***********AAAAA BBBB CCCC************" and does not kick my batch out, however, exists elsewhere. Thus, requiring the other parameters as it is unique within the file. and I want the next following: in sequence. Otherwise this "</Report>" exists above in another section I don't want and believe is causing issue. – T-Diddy 3 mins ago

    Okay, I thought so.

    Try this:

    @(setlocal
      ECHO OFF
      SET "_LogFile=C:\Admin\TestLog.log"
      SET "_MatchString_Begin=<Line Text="***********AAAAA BBBB CCCC************" />"
      SET "_MatchString_End=</Report>"
      SET "_Line#_Begin="
      SET "_Line#_End="
    )
    REM SET
    FOR /F "Delims=[]" %%# IN ('
      Find /N "%_MatchString_Begin:"=""%" "%_LogFile%" ^| FIND "["
    ') DO (
      IF NOT DEFINED _Line#_Begin (
        SET /A "_Line#_Begin=%%#-1"
        ECHO.SET /A "_Line#_Begin=%%#-1"
      )
    )
    FOR /F "SKIP=%_Line#_Begin% Tokens=* usebackq" %%_ IN (
      "%_LogFile%"
    ) DO (
      IF NOT DEFINED _Line#_End (
        ECHO(%%_
        ECHO("%%_" | FIND /I "%_MatchString_End%" &&(
          SET "_Line#_End=1"
        )
      )
    )
    PAUSE