Как извлечь часть строки, которая находится между двумя определенными строками, с помощью пакетного скрипта

Как извлечь часть строки, которая находится между двумя определенными строками, с помощью пакетного скрипта

Я пытаюсь извлечь строки, которые находятся между testid=и ].

Входной текстовый файл

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]

Ожидаемый результат

2345
12345678

решение1

Попробуй это,

@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

На выходе вы получите:

2345
12345678
Press any key to continue...

Если вы хотите избавиться от этой последней детали, замените

pause

в конце, с

pause > nul

и на выходе вы получите

2345
12345678

решение2

Это можно сделать с помощью пакетного файла, используя Regex в 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
::----------------------------------------------------------------------------------

Выходной файл выглядит так:

2345
12345678

решение3

Этот пакетный файл извлекает текст между (первым) testid= (если есть) в каждой строке и (первым) последующим ](если есть), независимо от того, где в строке они находятся, за одним исключением, которое мне удалось идентифицировать (см. нижнюю часть ответа):

@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позволяет разумно работать с переменными в цикле.
  • for /f "tokens=*" %%L in (input.txt)считывает input.txtпо одной строке и помещает каждую строку в индексную переменную %%L.
  • set line=%%Lкопирует текст в обычную переменную, с которой легче работать.
  • set right1=!line:*testid=! использует синтаксис для выполнения подстановки строк в расширении переменной (пробелы добавлены для ясности).% var : str1 = str2 %

    • Используется !вместо %из-за задержки расширения.
    • varэто line, очевидно.
    • str1is *testid*Это подстановочный знак (символ сопоставления с шаблоном), поэтому он соответствует всему вплоть до первого вхождения testidв  line. Обратите внимание, что, хотя мы хотели быstr1быть *testid=, но, к сожалению, это невозможно дляstr1содержать =, потому что =является разделителем междуstr1и str2.
    • str2нулевой.

    Таким образом, это заменяет все до первого вхождения testidin  lineна null и возвращает все после testid.

  • Если строка не содержит testid, то вышеприведенное возвращает весь line, без изменений. Так что, если lineравно right1, то в строке не было testid. Если они различны, то продолжаем анализировать эту строку.
  • set left=!right1:~0,1!извлекает первый (самый левый) символ из right1.
  • if "!left!" == "=", первый символ после testid=, поэтому мы нашли testid=и хотим продолжить анализ строки.
  • set right2=!right1:~1!устанавливает right2все, right1 за исключением первого символа; т. е. после  =.
  • for /f "tokens=1 delims=]" %%W in ("!right2!")распадается right2на части в первой части ], помещая текст до этого ]в %%W.
  • Если , то в строке %%W == !right2!не было .]
  • Если мы нашли testid=и ], то %%Wэто текст между ними. Вероятно, вам следует присвоить его обычной переменной.

Раскрытие информации: учитывая линию

[testid=a] and [testid=b]

этот пакетный файл найдет aтолько; он не найдет b. Учитывая строку

[testid<c] and [testid=d]

пакетный файл ничего не находит; первый testidего отбрасывает.

Связанный контент