我有一个cmdbatch file中的以下内容:
for /f %%l in (%2) do (for %%f in (%%l) do copy "%%f" %1))
注意:这个脚本基本上是读取一个文本文件,其中包含由%2(例如,其中包含c:\ test1 \ file1.cs; d:\ file2.js)给定path的分号分隔的txt文件,并将文件复制到目标由%1指定的文件夹。
我需要用%4
值replace%1
参数的string值x
(也传递给batch file,例如%3
),该值也作为parameter passing给batch file。
例如:
if %1 = 'test replace x with y' %3=x %4=y
所以输出结果应该是“用y代替y”
我怎样才能实现这一点使用Windows CMD批解释?
首先,您必须将%1
存储到变量中,然后才能执行替换。
基本上,替换的语法是这样的:
% variable : str1 = str2 %
这意味着: '用str2
替换每个str1
的variable
。
在你的情况下, str1
和str2
都是参数,而不是文字字符串。 直接使用上面的模板,你可能会得到这个表达式:
%variable:%3=%4%
。
但这会混淆解析器,因为它不知道应该先评估%3
和%4
。 事实上,它会首先尝试评估%variable:%
(和失败)。
在这种情况下,解决方案之一可能是使用一种称为“懒惰”延迟评估的方法 。 基本上,你正在将你正在评估一个变量的命令传递给CALL命令。 原始命令转换为“CALL版本”就像这样:
ECHO %var%
==> CALL ECHO %%var%%
。
请注意双%
s。 在解析时间,他们被评估为单个%
s。 最终的命令将被CALL再次解析,最终的效果与原始命令ECHO %var%
。
所以它和原来的命令是一样的(这是好的),我们在这里得到的是评估的后期 ,我的意思是最后的评估,当时这个变量被它的价值取代。 了解这种效果,我们可以用这样一种方式来构建我们的表达式:首先评估%3
和%4
,然后评估整个表达式。 具体来说就是这样的:
%%variable:%3=%4%%
在第一次解析之后,这个表达式会变成这样:
%variable:x=y%
这将被再次解析,输出将是variable
的修改内容。
为了更好的说明,下面是一个简单的例子:
SET "output=%1" CALL SET output=%%output:%3=%4%% ECHO %output%
UPDATE
还有另一种做同样的事情的方法,我应该首先提到。
Windows命令外壳支持正确的延迟扩展。 使用起来比较简单,但有一些注意事项。
首先,如何使用它。 延迟扩展的语法是!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!
情况下工作SET output=!output:%3=%4!
命令:
%3
和%4
立即进行评估,即在解析时间 – 分别用x
和y
代替;
命令变成这样: SET output=!output:x=y!
;
该命令即将执行 – !
表达式被评估( x
s被替换为y
s);
该命令被执行 – output
变量被修改。
现在关于警告。 首先要记住的是!
成为语法的一部分,无论何时遇到,都会被使用和解释。 所以你需要把它作为文字(如^!
)来转义。
另一个警告是SETLOCAL / ENDLOCAL块的主要作用。 问题是,这样一个块内环境变量的所有变化都是局部的。 在退出程序段时(在执行ENDLOCAL
)变量被设置为它在进入之前的值(在执行SETLOCAL
之前)。 这对你来说意味着output
的改变值只能在SETLOCAL
块中有效,你必须首先使用延迟扩展。 可能这在你的特定情况下可能不成问题,如果你只需要修改这个值然后马上使用它,但是你可能不得不记住它的未来。
注意:根据jeb的评论,你可以保存修改的值,并使用这个技巧离开SETLOCAL块:
ENDLOCAL & SET "output=%output%"
&
操作符只是在命令放在同一行时进行分隔。 它们按照指定的顺序依次执行。 就是在解析这一行的时候,SETLOCAL块还没有剩下,所以%output%
计算结果为修改后的值仍然有效。 但是赋值实际上是在 ENDLOCAL
之后执行的,也就是在离开块之后执行的。 所以你离开块之后有效的存储修改后的值,从而保留这些改变。 (谢谢, jeb !)
更多信息:
我已经尝试在Windows 7批处理文件下面的代码:
SET output=%1 CALL SET output=%output:unsigned=signed% CALL SET output=%output:.apk=-aligned.apk%
有用 !
如果需要在一个字符串中替换几个参数,只需使用“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