我在cmd批处理文件中有以下内容:
for /f %%l in (%2) do (for %%f in (%%l) do copy "%%f" %1))
注意:此脚本基本上是读取包含分号分隔的txt文件的文本文件,其路径由%2给出(例如,其中包含c:\ test1 \ file1.cs; d:\ file2.js)并复制文件到%1指定的目标文件夹。
我需要将%1
参数的字符串值x
(也传递给批处理文件,例如%3
)替换为%4
值,该值也作为参数传递批处理文件。
例如:
if %1 = 'test replace x with y'
%3=x
%4=y
所以输出应该'测试用y'替换y
如何使用Windows CMD批量解释器实现此目的?
答案 0 :(得分:49)
首先,您必须将%1
存储到变量中,然后才能执行替换。
基本上,替换的语法是:
%variable:str1=str2%
表示:'用str1
'替换variable
中的每个str2
。
在您的情况下,str1
和str2
都是参数,而不是文字字符串。直接使用上面的模板,您最终可能会得到以下表达式:
%variable:%3=%4%
。
但这会使解析器感到困惑,因为它不知道应该首先评估%3
和%4
。事实上,它首先会尝试评估%variable:%
(并失败)。
在这种情况下,其中一个解决方案可能是使用名为'lazy'延迟评估的方法。基本上,您将要评估变量的命令传递给CALL命令。将原始命令转换为“CALL版本”就像这样:
ECHO %var%
==> CALL ECHO %%var%%
。
请注意双%
秒。在解析时,它们被评估为单%
秒。生成的命令将由CALL再次解析,最终效果与原始命令ECHO %var%
的情况相同。
因此它与原始命令(这是好的)相同,我们在这里获得的是评估的后期,我的意思是最终的评估,当变量实际被替换时有它的价值。知道了这种效果,我们可以构造我们的表达式,首先评估%3
和%4
,然后是整个结果表达式。具体来说,像这样:
%%variable:%3=%4%%
在第一次解析后,这个表达式会变成这样:
%variable:x=y%
将再次解析,输出将是variable
的修改内容。
为了更好地说明,这是一个简单的工作示例:
SET "output=%1"
CALL SET output=%%output:%3=%4%%
ECHO %output%
<强>更新强>
还有另一种做同样事情的方法,我应该先提一下。
Windows命令shell支持正确的延迟扩展。它使用起来比较简单,但有一些注意事项。
首先,如何使用它。延迟扩展的语法为!var!
而不是%var%
,以便立即展开(它仍然有效,可以与延迟扩展语法一起使用)。
在使用以下命令启用语法之前,可能!var!
在脚本中不起作用:
SETLOCAL EnableDelayedExpansion
ENDLOCAL
命令关闭延迟扩展语法有效并由命令shell解释的块。
上面的示例脚本可以像这样重写:
SET "output=%1"
SETLOCAL EnableDelayedExpansion
SET output=!output:%3=%4!
ECHO !output!
ENDLOCAL
那么在SET output=!output:%3=%4!
命令的情况下这是如何工作的:
%3
和%4
,即在解析时 - 它们分别替换为x
和y
;
命令变为:SET output=!output:x=y!
;
该命令即将执行 - !
表达式已被评估(x
被y
s替换;
执行命令 - 修改output
变量。
现在关于警告。要记住的第一件事是!
成为语法的一部分,并在遇到时被消费和解释。所以你需要在它想要用作文字的地方(例如^!
)将其转义。
另一个警告是SETLOCAL / ENDLOCAL块的主要影响。问题是,这样一个区域内环境变量的所有变化都是本地的。退出块时(执行ENDLOCAL
时),变量设置为输入之前的值(执行SETLOCAL
之前)。这意味着,output
的更改值仅在您必须首先使用延迟扩展启动的SETLOCAL
块中有效。可能这在您的特定情况下可能不是问题,如果您只需要修改该值然后立即使用它,但您可能必须在将来记住它。
注意:根据 jeb 的注释,您可以保存修改后的值并使用此技巧保留SETLOCAL块:
ENDLOCAL & SET "output=%output%"
&
运算符只需将命令放在同一行上即可。它们按照指定的顺序依次执行。问题是,在解析该行的那一刻,还没有留下SETLOCAL块,因此%output%
计算修改后的值,该值仍然有效。但是,分配实际上是在 ENDLOCAL
之后执行的,即在离开块之后。因此,您在离开块后有效地存储修改后的值,从而保留更改。 (谢谢, jeb !)
更多信息:
答案 1 :(得分:1)
我在Windows 7批处理文件中试过以下代码:
SET output=%1
CALL SET output=%output:unsigned=signed%
CALL SET output=%output:.apk=-aligned.apk%
有效!
答案 2 :(得分:-1)
如果你需要在一个字符串中替换几个参数,只需使用“for / f”来设置前一个替换变量,如下所示:
SET "output1=%1"
CALL SET output1=%%output1:%3=%4%%
for /f "tokens=1" %%a in ('echo %output1%') do set output2=%%a
CALL SET output2=%%output2:%5%6%
for /f "tokens=1" %%a in ('echo %output2') do set output3=%%a