Я знаю из call /?
, что ~
переменная in (например %~d1
) используется для разбора части пути к файлу (в данном случае драйвера), но тильда здесь используется в другом контексте: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
Вот, в чем смысл этого расширения переменной: "!%1:~%len%!"
? И как оно вычисляет длину строки, сравнивая ее с пустой строкой? Каково назначение тильды здесь? Более того, этот пример заведет меня в бесконечный цикл, где находится вывод if not "!str:~136!" == "" set /A len+=1 & goto :strLen_Loop
(где число !str:~n
растет).
решение1
Знак тильда (~) используется в пакетных файлах по-разному:
Удаление кавычек аргумента. Знак тильды перед аргументом командной строки (например, "%~1") указывает на удаление окружающих кавычек из параметра. Например, если значение для %1 равно "Hi", то %~1 будет расширяться только до Hi.
Обработка подстроки. Существует способ извлечь подстроку из строковой переменной в пакетном файле. Синтаксис:
%variable:~num_chars_skip,num_chars_keep%
. Num chars skip означает точку, с которой следует начать строку, или исключить, сколько символов следует исключить перед строковой переменной. А num chars to keep указывает количество символов после начальной точки. Num chars to keep необязательно, но first обязательно. Если num chars to keep не указано, будет проанализирован только символ num chars to keep.
Для получения дополнительной помощи прочтите эти данные в командной строке:
call /?
for /?
set /?
надеюсь, это поможет
решение2
Пытаться set /?
:
...
Замена переменных окружения была улучшена следующим образом:%PATH:str1=str2%
расширит переменную среды PATH, заменив каждое вхождение «str1» в расширенном результате на «str2». «str2» может быть пустой строкой для эффективного удаления всех вхождений «str1» из расширенного вывода. «str1» может начинаться со звездочки, в этом случае она будет соответствовать всему от начала расширенного вывода до первого вхождения оставшейся части str1.
Также можно указать подстроки для расширения.
%PATH:~10,5%
расширит переменную среды PATH, а затем будет использовать только 5 символов, которые начинаются с 11-го (смещение 10) символа расширенного результата. Если длина не указана, то по умолчанию используется остаток значения переменной. Если любое из чисел (смещение или длина) отрицательно, то используемое число представляет собой длину значения переменной среды, добавленную к указанному смещению или длине.
%PATH:~-10%
извлечет последние 10 символов переменной PATH.
%PATH:~0,-2%
извлечет все символы переменной PATH, кроме последних двух.
...
Theповедениеочень полезно, ноописаниеоб отрицательных числах одновременно запутанно и неточно. Это верно для первого числа (смещение): %VAR:~N%
начинается с минуса в конце N
. При использовании отрицательного числа длявторойчисло, это больше не подстрокадлина, но интерпретируется как количество символов, которые нужно остановить до концаценить, независимо от его длины. Так что %VAR:~1,-1%
дает значение, за исключением первого и последнего символов, а оба %VAR:~-2,-1%
и %VAR:~-2,1%
дают предпоследний символ.
решение3
- Чтобы «исправить» этот учебный код и предотвратить бесконечный цикл, цитируем в комментарии:
Ясно, но все же, в моей машине мне нужно ^C, чтобы завершить его. Просто посмотрите, какое большое число я получаю - 136 - хотя нет длины или слова с 136 символами- @Пастух
@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