批处理变量中的波浪号 ~ 是什么意思?

批处理变量中的波浪号 ~ 是什么意思?

我从中知道call /?~变量(例如%~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 是可选的,但第一个是必需的。如果没有指定 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 环境变量,然后仅使用从扩展结果的第 11 个(偏移量 10)字符开始的 5 个字符。如果未指定长度,则默认为变量值的余数。如果任一数字(偏移量或长度)为负数,则使用的数字是环境变量值的长度加上指定的偏移量或长度。

%PATH:~-10%

将提取 PATH 变量的最后 10 个字符。

%PATH:~0,-2%

将提取 PATH 变量中除最后 2 个字符之外的所有字符
。...

行为非常有用,但是描述关于负数的误解既令人困惑又不准确。对于第一个数字(偏移量)来说,它是正确的:%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

相关内容