Pregunta Windows Batch comprueba si la variable comienza con, termina con y contiene una cadena específica


Estoy tratando de verificar si una variable en un archivo por lotes comienza con " contiene BETA en algún lugar y termina con ").

¿Es posible? Y si es así, ¿alguien puede ayudarme con eso?


8
2018-03-29 16:53


origen


Respuestas:


@ECHO OFF
SETLOCAL
SET var=abc&CALL :check
SET var="abc"&CALL :llcheck
SET var="")&CALL :check
SET var=")"&CALL :llcheck
SET var=abc")"&CALL :llcheck
SET var=xyzbetazyx&CALL :check
SET var="xyzbetazyx"&CALL :llcheck
SET var=xyzbetazyx")"&CALL :llcheck
SET var=xyzbetazyx")"&CALL :check
SET var="xyzbetazyx")&CALL :check
GOTO :eof
:: Lop last, then check
:llcheck
SET var=%var:~0,-1%
:check
SET result=N
SET var2=%var%
SET varvar=%var%

>test1.txt ECHO %var:~0,1%%var:~-2%
>test2.txt ECHO "")
FC test1.txt test2.txt >nul
IF ERRORLEVEL 1 GOTO done
SET var|FINDSTR /b "var="|FINDSTR /i "beta" >nul
IF ERRORLEVEL 1 GOTO done
SET result=Y
:done
ECHO %var% starts " has BETA and ends ") : %result% 
GOTO :eof

Donde hay voluntad ...

Establecer variables con desequilibrio " puede ser complicado Lo configuré equilibrado y corté el último carácter (:llcheck entrada: lop último y check.

Essentiall, he copiado la variable en var2 y varvar para mostrar lo que ocurre si se configuran estos nombres de variables.

Se generan dos archivos. TEST1.TXT contiene el primer y último 2 caracteres de var y TEST2.TXT simplemente "")

Compara los dos: si no son idénticos, entonces la variable NO comienza " y punto ") De lo contrario bien, podría simplemente haber escrito var a un archivo y utilizado findstr encontrar beta, pero decidí enviar la salida de SET var que debería ser el contenido de ALL del var* variables en la forma

var=abc
var2=abc
varvar=abc

en findstr, encontrando el que comienza (/b) var= y encontrar si ESE contiene la cadena beta los /i selecciona insensible a mayúsculas / minúsculas. Si quieres específicamente BETA en MAYÚSCULAS, simplemente cambie beta a BETA y eliminar el /i.

result se establece en Y o N


4
2018-03-29 18:00



Suponiendo que su variable no contiene ninguna línea de alimentación o devoluciones de carro, entonces todo lo que se necesita es un solo comando FINDSTR. Tiene soporte de expresión regular limitado que es más que suficiente para este problema.

@echo off
setlocal
set test1=abc
set test2="abc"
set test3="")
set test4=")"
set test5=abc")"
set test6=xyzBETAzyx
set test7="xyz BETA zyx"
set test8=xyzBETAzyx")"
set test9=xyzBETAzyx")"
set test10="xyzbetazyx")
set test11="xyzBETAzyx")

for /l %%N in (1 1 11) do call :test test%%N
exit /b

:test  variableName
setlocal enableDelayedExpansion
echo !%1!|>nul findstr /rx \".*BETA.*\") && set "result=PASS" || set "result=FAIL"
echo %1 = !result!: !%1!
exit /b

Solo pasa TEST11.

los /R opción fuerza a que la cadena de búsqueda sea tratada como una expresión regular.

los /X opción significa que debe ser una coincidencia exacta: toda la cadena debe coincidir con la cadena de búsqueda.

.* es la expresión del comodín regex que coincidirá con cualquier cadena de caracteres.

Redirijo la salida de FINDSTR a NUL porque no necesitamos ver la línea. Solo queremos el código de retorno

FINDSTR requiere que los literales de comillas dobles se escapen como \"

Use la expansión retrasada para que pueda hacer eco con seguridad de cualquier valor dentro de la variable.

yo suelo && para tomar medidas condicionalmente cuando FINDSTR tuvo éxito, y || para tomar medidas condicionalmente cuando FINDSTR falló.

Mi :TEST la rutina toma el nombre de la variable como el único argumento.

Tenga en cuenta que, en algunas situaciones, el analizador de lotes requiere que también escape de la comilla doble como ^", lo que significa que una cita totalmente escapada se verá como \^". Pero esa complicación no es necesaria en su caso. Las reglas de escape de FINDSTR son en realidad un poco inseguras. Ver ¿Cuáles son las características y limitaciones no documentadas del comando FINDSTR de Windows? para más información.

Mi código de prueba hace una búsqueda sensible a mayúsculas y minúsculas. Asi que beta no coincidirá BETA. Si desea una búsqueda insensible a mayúsculas y minúsculas, simplemente agregue la /I opción.

EDITAR: 2015-07-22

Otra opción, si y solo si desea ignorar el caso, es usar una combinación de búsqueda / reemplazo de expansión variable y operaciones de subcadenas de expansión. Tanto test10 como test11 pasan a continuación.

@echo off
setlocal
set test1=abc
set test2="abc"
set test3="")
set test4=")"
set test5=abc")"
set test6=xyzBETAzyx
set test7="xyz BETA zyx"
set test8=xyzBETAzyx")"
set test9=xyzBETAzyx")"
set test10="xyzbetazyx")
set test11="xyzBETAzyx")

for /l %%N in (1 1 11) do call :test test%%N
exit /b

:test  variableName
setlocal enableDelayedExpansion
set "result=FAIL"
if "!%1:beta=!" neq "!%1!" if "!%1:~0,1!" equ ^""" if "!%1:~-2!" equ ^"")" set "result=PASS"
echo %1 = !result!: !%1!
exit /b

El primer IF comprueba beta en cualquier lugar (sin distinción de mayúsculas y minúsculas). El segundo IF verifica " al principio, y el último IF comprueba ") al final. Lo único difícil es averiguar cómo escapar de la cadena de comparación cuando tiene un número impar de comillas.


11
2018-03-31 15:04



@echo off
setlocal EnableDelayedExpansion
set quote="
set variable="This must be true: BETA")
echo Variable=!variable!
if "!variable:~0,1!" equ "!quote!" (
   rem Start with "
   if "!variable:BETA=!" neq "!variable!" (
      rem Contains BETA
      if "!variable:~-2!" equ "!quote!^)" (
         echo TRUE: it start with " contains BETA and ends with "^)
      ) else (
         echo FALSE, it does not ends with "^)
      )
   ) else (
      echo FALSE, it does not contain BETA
   )
) else (
   echo FALSE, it does not start with "
)

Salida:

Variable="This must be true: BETA")
TRUE: it start with " contains BETA and ends with ")
  • La forma de lidiar con las comillas no balanceadas (y con otros caracteres especiales de Batch, de hecho) es usar la Expansión retrasada: de esta manera, las comillas y los caracteres especiales no aparecen en la línea de comando que se está analizando.

  • Recuerde escaparse con ^ cualquier paréntesis derecho que no esté cerrando paréntesis de bloques de comandos.

  • Una forma fácil de comprobar si una variable contiene una cadena determinada es intentar eliminar la cadena del valor de la variable: si el resultado es diferente del valor original, la variable contiene la cadena.

Antonio


2
2018-03-29 18:49