Cómo extraer una parte de una línea que se encuentra entre dos cadenas específicas mediante un script por lotes

Cómo extraer una parte de una línea que se encuentra entre dos cadenas específicas mediante un script por lotes

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 enabledelayedexpansionle permite trabajar de forma inteligente con variables en bucles.
  • for /f "tokens=*" %%L in (input.txt)Lee input.txtuna línea a la vez y coloca cada línea en la variable de índice %%L.
  • set line=%%Lcopia 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.
    • vares line, obviamente.
    • str1es *testid. Es  *un comodín (símbolo de coincidencia de patrón), por lo que coincide con todo hasta la primera aparición de testidin  line. Tenga en cuenta que, si bien nos gustaríastr1serlo *testid=, pero desgraciadamente es imposiblestr1contener =, porque =es el delimitador entrestr1str2.
    • str2es nulo.

    Entonces esto reemplaza todo hasta la primera aparición de testidin  linecon nulo y devuelve todo después testid.

  • Si la línea no contiene testid, lo anterior devuelve el archivo completo line, sin cambios. Entonces, si linees igual a right1, no había ningún testiden 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) de right1.
  • if "!left!" == "=", el primer carácter después testides =, así que hemos encontrado testid=y queremos seguir analizando la línea.
  • set right2=!right1:~1!se establece right2para que sea todo right1 excepto el primer carácter; es decir, después del  =.
  • for /f "tokens=1 delims=]" %%W in ("!right2!")se rompe right2en el primero ], poniendo el texto anterior ]en %%W.
  • Si %%W == !right2!, no había nadie ]en la fila.
  • Si encontramos testid=y ], entonces %%Westá 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 testidlo descarta.

información relacionada