
Estoy intentando extraer cadenas que están entre testid=
y ]
.
Archivo 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]
Rendimiento esperado
2345
12345678
Respuesta1
Prueba esto,
@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
El resultado que obtendrás es,
2345
12345678
Press any key to continue...
Si desea deshacerse de ese último bit, reemplace el
pause
al final, con un
pause > nul
y el resultado que obtendrás es
2345
12345678
Respuesta2
Puedes hacerlo con un archivo por lotes usando Regex en 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
::----------------------------------------------------------------------------------
El archivo de salida es así:
2345
12345678
Respuesta3
Este archivo por lotes extrae el texto entre (el primero) testid=
(si corresponde) en cada línea y el (primero) posterior ]
(si corresponde), independientemente de en qué parte de la línea aparezcan, con una excepción que pude identificar (ver parte inferior de la respuesta):
@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
le permite trabajar de forma inteligente con variables en bucles.for /f "tokens=*" %%L in (input.txt)
Leeinput.txt
una línea a la vez y coloca cada línea en la variable de índice%%L
.set line=%%L
copia el texto en una variable normal, que es más fácil de manipular.set right1=!line:*testid=!
utiliza la sintaxis para realizar una sustitución de cadenas en una expansión de variable (se agregan espacios para mayor claridad).% var : str1 = str2 %
- Usar
!
en lugar de%
debido a la expansión retrasada. var
esline
, obviamente.str1
es*testid
. Es*
un comodín (símbolo de coincidencia de patrón), por lo que coincide con todo hasta la primera aparición detestid
inline
. Tenga en cuenta que, si bien nos gustaríastr1
serlo*testid=
, pero desgraciadamente es imposiblestr1
contener=
, porque=
es el delimitador entrestr1
ystr2
.str2
es nulo.
Entonces esto reemplaza todo hasta la primera aparición de
testid
inline
con nulo y devuelve todo despuéstestid
.- Usar
- Si la línea no contiene
testid
, lo anterior devuelve el archivo completoline
, sin cambios. Entonces, siline
es igual aright1
, no había ningúntestid
en la línea. Si son diferentes, proceda a analizar esta línea. set left=!right1:~0,1!
extrae el primer carácter (el más a la izquierda) deright1
.if "!left!" == "="
, el primer carácter despuéstestid
es=
, así que hemos encontradotestid=
y queremos seguir analizando la línea.set right2=!right1:~1!
se estableceright2
para que sea todoright1
excepto el primer carácter; es decir, después del=
.for /f "tokens=1 delims=]" %%W in ("!right2!")
se romperight2
en el primero]
, poniendo el texto anterior]
en%%W
.- Si
%%W == !right2!
, no había nadie]
en la fila. - Si encontramos
testid=
y]
, entonces%%W
está el texto entre ellos. Probablemente deberías asignarlo a una variable normal.
Divulgación: dada la línea
[testid=a] and [testid=b]
este archivo por lotes solo encontrará a
; no lo encontrará b
. dada la linea
[testid<c] and [testid=d]
el archivo por lotes no encontrará nada; el primero testid
lo descarta.