首先,您需要将%1
存储到变量中,然后才能进行替换。
基本上,替换的语法如下:
%<i>variable</i>:<i>str1</i>=<i>str2</i>%
这意味着:'用str2替换variable中的每个str1'。
在您的情况下,str1和str2都是参数,而不是字面字符串。直接使用上述模板可能会得到以下表达式:
%variable:%3=%4%
但这会使解析器困惑,因为它不知道%3和%4应该先评估。事实上,它会首先尝试评估%variable:%(并失败)。
在这种情况下的解决方案之一是使用一种称为“延迟”延迟评估的方法。基本上,您正在将评估变量的命令传递给CALL命令。原始命令转换为其'CALL版本'的过程如下:
ECHO %var% ==> CALL ECHO %%var%%。
请注意双%号。在解析时间,它们被评估为单个%。最终效果与原始命令ECHO %var%相同。
所以它的工作方式与原始命令相同(这很好),我们在这里获得的是更晚的评估时间,我的意思是最终评估,当变量实际上被其值替换时。了解到这种效果后,我们可以构造我们的表达式,使%3
和%4
首先被评估,然后才是整个结果表达式。具体来说,就像这样:
%%variable:%3=%4%%
第一次解析后,该表达式将变成以下内容:
%variable:x=y%
这将再次进行解析,输出将是variable
修改后的内容。
为更好地说明,这里有一个简单的工作示例:
SET "output=%1"
CALL SET output=%%output:%3=%4%%
ECHO %output%
更新
还有一种方法可以完成同样的事情,我应该先提到它。
Windows命令行支持一个真正的延迟扩展。使用起来更简单,但也有一些注意事项。
首先,如何使用它。延迟扩展的语法是!var!
,而不是立即扩展的%var%
(立即扩展仍然有效,并且可以与延迟扩展语法一起使用)。
可能在您的脚本中!var!
不会起作用,直到您使用以下命令启用语法:
SETLOCAL EnableDelayedExpansion
< p >
ENDLOCAL
命令关闭延迟扩展语法在命令 shell 中有效并被解释的块。
以上示例脚本可以重写如下:
SET "output=%1"
SETLOCAL EnableDelayedExpansion
SET output=!output:%3=%4!
ECHO !output!
ENDLOCAL
对于SET output=!output:%3=%4!
命令的工作原理:
现在来谈谈注意事项。首先要记住的是,!
成为语法的一部分,并且每当遇到它时都会被消耗和解释。因此,您需要在想要将其用作字面值的位置进行转义(例如^!
)。
另一个需要注意的是SETLOCAL/ENDLOCAL块的主要影响。问题在于,这种块内环境变量的所有更改都是本地的。退出块(执行ENDLOCAL)时,变量将设置为进入之前的值(执行SETLOCAL之前的值)。这意味着对于您而言,output的更改值仅在您必须启动SETLOCAL块以使用延迟扩展的情况下才有效。如果您只需要修改值然后立即使用它,则可能不会出现问题,但您应该记住这一点以备将来之需。
注意:根据jeb的评论,您可以使用以下技巧保存修改后的值并离开SETLOCAL块:
ENDLOCAL & SET "output=%output%"
&
运算符只是在同一行上放置命令时的分隔符。它们按照指定的顺序一个接一个地执行。问题在于,在解析该行时,SETLOCAL块尚未离开,因此
%output%
求值为修改后的值,仍然有效。但是赋值实际上是在
ENDLOCAL
之后执行的,即在离开块之后执行。因此,您实际上是在离开块后存储修改后的值,从而保留了更改。(感谢
jeb!)
更多信息:
- 关于延迟扩展:
在子字符串替换方面: