为什么 CALL SET 在 CMD Windows 中的工作方式与 .CMD文件?



我正在尝试以编程方式使用Windows CMDSET字符串操作版本。SET的两个版本是...

SET New_String=%String:Old_Text=New_Text%

在变量String中,将Old_Text替换为New_Text,并返回变量New_String的结果。

SET New_String=%String:~Number_Of_Chars_To_Skip,Number_Of_Chars_To_Keep%

在变量String跳过Number_Of_Chars_To_Skip后提取Number_Of_Chars_To_Keep,并返回变量New_String

Old_Text, New_Text, Number_Of_Chars_To_Skip, Number_Of_Chars_To_Keep必须都是文字,而不是变量。所以,典型的用法是这样的...

SET New_String=%String:abcd=fghi%
SET New_String=%String:~2,4%

这样的用法不起作用...

SET New_String=%String:%Old_Text%=%New_Text%%
SET New_String=%String:~%Skip_Count%,%Keep_Count%%

要执行上述两个SET,您必须CALL SET,例如...

CALL SET New_String=%%String:%Old_Text%=%New_Text%%%
CALL SET New_String=%%String:~%Skip_Count%,%Keep_Count%%%

所以,我有以下测试代码片段...

SET "Chars=" & SET "String=0123456789" & SET "Skip=1" & SET "Keep=3"
CALL SET Chars=%%String:~%Skip%,%Keep%%%
ECHO Chars="%Chars%" (expected to be "123")

从CMD文件中,这工作正常。CALL已扩展到SET Chars=%string:~1,3%,并返回预期结果 123。但是,一个很大的但是,从CMD窗口(具有相同的变量)中,完全相同的CALL SET返回此...

%0123456789Skip%,3%%

为什么这在CMD窗口中不起作用?我四处研究了一下,没有找到任何解释原因的信息。

根据线程 Windows 命令解释器 (CMD.EXE) 如何解析脚本?,批处理文件和命令行的解析方式不同,尤其是在环境变量扩展方面。

批处理文件解析器将两个连续的百分号替换为一个文字百分号,而命令行解析器则不然。 因此,CALL SET Chars=%%String:~%Skip%,%Keep%%%批处理文件中工作,但不能在cmd中工作。

要在cmd中实现相同的资源,您可以使用以下内容:

CALL SET Chars=%^String:~%Skip%,%Keep%%

实际上,这只指定一个名为^String的变量,该变量预计不会定义。与批处理文件分析器相比,命令行解析器不会用空字符串替换未定义的变量,因此^String按字面保留。考虑到^是在变量扩展%处理的。变量%Skip%%Keep%按预期扩展,因此生成的表达式SET Chars=%String:~1,3%

要证明这一点,只需执行SET String=something,因此结果将是ome


请注意,引用的SET语法CALL SET "Chars=%^String:~%Skip%,%Keep%%"失败,因为这会隐藏分析器中的转义字符^。但是,您可以改用转义引号:

CALL SET ^"Chars=%^String:~%Skip%,%Keep%%^"

最新更新