
Я пытаюсь извлечь строки, которые находятся между 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
, очевидно.str1
is*testid
.*
Это подстановочный знак (символ сопоставления с шаблоном), поэтому он соответствует всему вплоть до первого вхожденияtestid
вline
. Обратите внимание, что, хотя мы хотели быstr1
быть*testid=
, но, к сожалению, это невозможно дляstr1
содержать=
, потому что=
является разделителем междуstr1
иstr2
.str2
нулевой.
Таким образом, это заменяет все до первого вхождения
testid
inline
на 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
его отбрасывает.