
Estou tentando extrair strings que estão entre testid=
e ]
.
Arquivo de texto de entrada
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]
Resultado esperado
2345
12345678
Responder1
Tente isso,
@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
A saída que você obterá é,
2345
12345678
Press any key to continue...
Se você quiser se livrar dessa última parte, substitua o
pause
no final, com um
pause > nul
e a saída que você obterá é
2345
12345678
Responder2
Você pode fazer isso com um arquivo em lote usando Regex em 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
::----------------------------------------------------------------------------------
O arquivo de saída é assim:
2345
12345678
Responder3
Este arquivo em lote extrai o texto entre (o primeiro) testid=
(se houver) em cada linha e o (primeiro) subsequente ]
(se houver), independentemente de onde eles aparecem na linha, com uma exceção que consegui identificar (veja parte inferior da resposta):
@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
permite trabalhar de forma inteligente com variáveis em loops.for /f "tokens=*" %%L in (input.txt)
lêinput.txt
uma linha por vez e coloca cada linha na variável de índice%%L
.set line=%%L
copia o texto em uma variável regular, que é mais fácil de manipular.set right1=!line:*testid=!
usa a sintaxe para fazer uma substituição de string em uma expansão de variável (espaços são adicionados para maior clareza).% var : str1 = str2 %
- Usando
!
em vez de%
devido à expansão atrasada. var
éline
, obviamente.str1
é*testid
. O*
é um curinga (símbolo de correspondência de padrão), portanto, corresponde a tudo até a primeira ocorrência detestid
inline
. Observe que, embora gostaríamosstr1
ser*testid=
, mas, infelizmente, é impossível parastr1
conter=
, porque=
é o delimitador entrestr1
estr2
.str2
é nulo.
Portanto, isso substitui tudo até a primeira ocorrência de
testid
inline
por null e retorna tudo depois detestid
.- Usando
- Se a linha não contiver
testid
, o valor acima retornará o valor inteiroline
, inalterado. Então, seline
for igualright1
, não havia nenhumtestid
na linha. Se forem diferentes, prossiga para a análise desta linha. set left=!right1:~0,1!
extrai o primeiro caractere (mais à esquerda) deright1
.if "!left!" == "="
, o primeiro caractere depoistestid
é=
, então encontramostestid=
e queremos continuar analisando a linha.set right2=!right1:~1!
defineright2
como todos,right1
exceto o primeiro caractere; ou seja, depois do=
.for /f "tokens=1 delims=]" %%W in ("!right2!")
se separaright2
no primeiro]
, colocando o texto antes]
em%%W
.- Se
%%W == !right2!
, não havia nenhum]
na fila. - Se encontrarmos
testid=
e]
, então%%W
o texto está entre eles. Você provavelmente deveria atribuí-lo a uma variável regular.
Divulgação: dada a linha
[testid=a] and [testid=b]
este arquivo em lote encontrará a
apenas; não encontrará b
. Dada a linha
[testid<c] and [testid=d]
o arquivo em lote não encontrará nada; o primeiro testid
joga fora.