1

I am trying to extract strings which are between testid= and ].

Input text file

SEVERE  TEST 11/18/2019 8:00:41 AM  Could not find INPUT with [testid=2345]
SEVERE  TEST 11/18/2019 5:02:11 AM  Could not find INPUT with [testid=12345678]

Expected output

2345
12345678
3
  • Welcome to Super User! On this Q&A site we try to provide answers to well-asked questions. A part of asking a good question is doing some research before you ask, and letting us know what you already tried. Please update your question so that it shows that you put in some effort before posting your question here.
    – Cas
    Nov 18, 2019 at 9:38
  • Other than the date and time, will each line of the input text file always read the same as above or does the text also change? my point being, you could scan each line until you hit the = sign, then capture the numbers until you hit the ] sign. Another method might be to start with the last character ] and back up until you hit the = sign.
    – Larryc
    Nov 18, 2019 at 20:40
  • You could do this quite easily with vb script.
    – Lumberjack
    Nov 18, 2019 at 21:23

3 Answers 3

1

Try this,

@echo off
for /F "tokens=* USEBACKQ" %%F in (`findstr /I /C:"8:00:41" text.txt`) do (
set string=%%F
)
set string=%string:~68%
set string=%string:~,-1%
echo %string%
for /F "tokens=* USEBACKQ" %%F in (`findstr /I /C:"5:02:11" text.txt`) do (
set string2=%%F
)
set string2=%string2:~68%
set string2=%string2:~,-1%
echo %string2%
pause

The output you'll get is,

2345
12345678
Press any key to continue...

If you want to get rid of that last bit, replace the

pause

at the end, with a

pause > nul

and the output you'll get is

2345
12345678
0

You can do it with a batch file using Regex in vbscript :

@echo off
Title Extract Data between string and char from a text file using RegExp
Set "InputFile=Test.txt"
Set "OutputFile=OutputFile.txt"
Call :ExtractData "%InputFile%" "%OutputFile%"
If Exist %OutputFile% Start "" %OutputFile%
Exit
::-----------------------------------------------------------------------------------
:ExtractData <InputFile> <OutputFile>
(
    echo WScript.StdOut.WriteLine Extract("%~1"^)
    echo Function Extract(Data^)
    echo Dim strPattern,strResult,oRegExp,Match,colMatches 
    echo Data = WScript.StdIn.ReadAll
    echo strPattern = "\[testid=(.+)\]"
    echo Set oRegExp = New RegExp
    echo oRegExp.Global = True
    echo oRegExp.Multiline = True
    echo oRegExp.IgnoreCase = True 
    echo oRegExp.Pattern = strPattern
    echo set colMatches = oRegExp.Execute(Data^)
    echo For Each Match in colMatches
    echo    strResult = strResult ^& Match.SubMatches(0^) ^& vbcrlf
    echo Next
    echo Extract = strResult
    echo End Function
)>"%tmp%\%~n0.vbs"
cscript //nologo "%tmp%\%~n0.vbs" < "%~1" > "%~2"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
Exit /B
::----------------------------------------------------------------------------------

The output file is like this :

2345
12345678
0

This batch file with extract the text between (the first) testid= (if any) on each line and the (first) subsequent ] (if any), regardless of where in the line they appear, with one exception that I was able to identify (see bottom of answer):

@echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%L in (input.txt) do (
    set line=%%L
    set right1=!line:*testid=!
    if not !line! == !right1! (
        set left=!right1:~0,1!
        if "!left!" == "=" (
            set right2=!right1:~1!
            for /f "tokens=1 delims=]" %%W in ("!right2!") do (
                if not %%W == !right2! (
                    echo.%%W
                )
            )
        )
    )
)
  • setlocal enabledelayedexpansion lets you work intelligently with variables in loops.
  • for /f "tokens=*" %%L in (input.txt) reads input.txt a line at a time and puts each line into index variable %%L.
  • set line=%%L copies the text into a regular variable, which is easier to manipulate.
  • set right1=!line:*testid=! uses the % var : str1 = str2 % syntax for doing a string substitution in a variable expansion (spaces are added for clarity).

    • Using ! instead of % because of delayed expansion.
    • var is line, obviously.
    • str1 is *testid.  The * is a wildcard (pattern matching symbol), so this matches everything up through the first occurrence of testid in line.  Note that, while we would like str1 to be *testid=, but, unfortunately, it’s impossible for str1 to contain =, because = is the delimiter between str1 and str2.
    • str2 is null.

    So this replaces everything up through the first occurrence of testid in line with null, and returns everything after testid.

  • If the line doesn’t contain testid, the above returns the entire line, unchanged.  So, if line equals right1, there was no testid in the line.  If they are different, proceed to analyze this line.
  • set left=!right1:~0,1! extracts the first (leftmost) character from right1.
  • if "!left!" == "=", the first character after testid is =, so we have found testid= and we want to continue analyzing the line.
  • set right2=!right1:~1! sets right2 to be all of right1 except for the first character; i.e., after the =.
  • for /f "tokens=1 delims=]" %%W in ("!right2!") breaks right2 apart at the first ], putting the text before ] into %%W.
  • If %%W == !right2!, there was no ] in the line.
  • If we found testid= and ], then %%W is the text between them. You should probably assign it to a regular variable.

Disclosure: given the line

[testid=a] and [testid=b]

this batch file will find a only; it will not find b.  Given the line

[testid<c] and [testid=d]

the batch file will not find anything; the first testid throws it off.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.