Sé por call /?
, que la ~
variable in (por ejemplo %~d1
) se usa para analizar una parte de la ruta del archivo (controlador aquí), pero la tilde se usa en otro contexto aquí:https://www.tutorialspoint.com/batch_script/batch_script_string_length.htm:
@echo off
set str = Hello World
call :strLen str strlen
echo String is %strlen% characters long
exit /b
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
goto :eof
Aquí, ¿cuál es el significado de esta expansión variable "!%1:~%len%!"
? ¿Y cómo calcula la longitud de la cadena comparándola con una cadena vacía? ¿Cuál es el propósito de la tilde aquí? Además, este ejemplo me llevará a un bucle infinito donde está la salida if not "!str:~136!" == "" set /A len+=1 & goto :strLen_Loop
(donde crece el número !str:~n
).
Respuesta1
El signo de tilde (~) se utiliza de diferentes maneras en archivos por lotes:
Eliminación de citas de argumentos. Un signo de tilde antes de un argumento de línea de comando (como "%~1") indica que se deben eliminar las comillas circundantes del parámetro. Por ejemplo, si el valor de %1 es "Hola", entonces %~1 se expandirá solo a Hola.
Procesamiento de subcadenas. Hay una manera de extraer una subcadena de una variable de cadena en un archivo por lotes. La sintaxis es:
%variable:~num_chars_skip,num_chars_keep%
. Num chars skip significa el punto donde comenzar en la cadena, o excluir cuántos caracteres preceden a la variable de cadena. Y num chars to keep indica la cantidad de caracteres después del punto de inicio. El número de caracteres a conservar es opcional, pero el primero es obligatorio. Si no se especifica el número de caracteres a conservar, solo se analizará el número de caracteres a conservar.
Deberías leerlos en el símbolo del sistema para obtener más ayuda:
call /?
for /?
set /?
Espero que ayude
Respuesta2
Intentar set /?
:
...
La sustitución de variables de entorno se ha mejorado de la siguiente manera:%PATH:str1=str2%
expandiría la variable de entorno PATH, sustituyendo cada aparición de "str1" en el resultado expandido con "str2". "str2" puede ser la cadena vacía para eliminar efectivamente todas las apariciones de "str1" de la salida expandida. "str1" puede comenzar con un asterisco, en cuyo caso coincidirá con todo, desde el comienzo de la salida expandida hasta la primera aparición de la parte restante de str1.
También puede especificar subcadenas para una expansión.
%PATH:~10,5%
expandiría la variable de entorno PATH y luego usaría solo los 5 caracteres que comienzan en el carácter 11 (desplazamiento 10) del resultado expandido. Si no se especifica la longitud, el valor predeterminado es el resto del valor de la variable. Si cualquiera de los números (desplazamiento o longitud) es negativo, entonces el número utilizado es la longitud del valor de la variable de entorno agregado al desplazamiento o longitud especificado.
%PATH:~-10%
extraería los últimos 10 caracteres de la variable PATH.
%PATH:~0,-2%
extraería todos menos los últimos 2 caracteres de la variable PATH.
...
Elcomportamientoes muy útil, pero eldescripciónsobre números negativos es a la vez confuso e inexacto. Es correcto para el primer número (el desplazamiento): %VAR:~N%
comienza al final menos N
los caracteres. Cuando se utiliza un número negativo para elsegundonúmero, ya no es la subcadenalongitud, pero interpretado como cuántos caracteres detener antes del final delvalor, independientemente de su longitud. Entonces %VAR:~1,-1%
da el valor excepto el primer y último carácter, y ambos %VAR:~-2,-1%
dan %VAR:~-2,1%
el penúltimo carácter.
Respuesta3
- Para "arreglar" el código de este tutorial y evitar que el bucle sea infinito, citado en el comentario:
Ya veo, pero aún así, en mi máquina necesito ^C para finalizarlo. Solo mire el número grande que obtengo, 136, aunque no hay longitud ni palabra con 136 caracteres.- @Pastor
@echo off && setlocal enabledelayedexpansion
set "_str=Hello World" & call :strLen_Loop str
:strLen_Loop
if "%~1" == "" (
endlocal & goto :EOF
) else if not "!_%~1:~%_len%!" == "" (
set /A "_len+=1" & goto=:strLen_Loop
) else echo\String is !_len! characters long & exit /b