bee*_*ear 3 windows batch find-and-replace string
我试图了解 Windows 批处理中的字符串替换实际上是如何工作的并且遇到了问题。
@echo off
set var=wild
set varnew=%var:l=n%
echo var is: %var%
echo varnew is: %varnew%
Run Code Online (Sandbox Code Playgroud)
确实有效;它生成预期的输出:
var is: wild
varnew is: wind
Run Code Online (Sandbox Code Playgroud)
但这不是(示例目录“Main”):
@echo off
for /D %%G IN (*) do (
setlocal
echo G is: %%G
set _srcp=%%G
echo _srcp is %_srcp%
rem set _newp=%_newp:ai=_01_% <-- confused variable
set _newp=%_srcp:ai=_01_%
echo._newp is: %_newp%
endlocal
)
Run Code Online (Sandbox Code Playgroud)
它生成此输出:
G is: Main
_srcp is Main
_newp is: %_srcp:ai=_01_
Run Code Online (Sandbox Code Playgroud)
我希望代码生_newp is: M_01_n成为最后一行。我在这里真的没有想法,有人可以指出我正确的方向吗?
BB
你有几个问题:
%var%在解析语句时会发生扩展,并且在执行任何命令之前,一次解析整个括号内的代码块。所以该值是循环开始之前存在的值。解决方案是延迟扩展,它发生在循环中的每个命令正在执行时。
你的逻辑是错误的 - _newp 的分配应该基于 _srcp 的值
CMD 处理器是一个复杂的野兽(而且文档也很差)。各种类型的变量的扩展点有很多,如果你真的想充分利用批处理编程,你必须充分理解它们。链接里都有说明,但总结一下,展开的顺序是:
1) % expand - Parameter: echo %1 or Environment variable: echo %var%
---- 大多数解析现在已经完成 ----
2) FOR 变量扩展: for %%A in (*) do echo %%A
3) Delayed environment variable expand: echo !var!
4) CALL % expand - Parameter: call echo %%1 or Environment variable: call echo %%var%%
5) SET /A 环境变量扩展:`set /a "value=var+1"
请注意,延迟扩展需要通过以下方式启用延迟扩展 SETLOCAL EnableDelayedExpansion
以下使用延迟扩展的代码将给出您寻求的结果:
@echo off
for /D %%G in (*) do (
setlocal enableDelayedExpansion
echo G is: %%G
set "_srcp=%%G"
echo _srcp is !_srcp!
set "_newp=!_srcp:ai=_01_!"
echo _newp is: !_newp!
endlocal
)
Run Code Online (Sandbox Code Playgroud)
请注意,延迟扩展FOR变量扩展之后发生,所以,结果将如果被损坏%%Gconstains !。这可以通过额外的 SETLOCAL 来避免:
for /D %%G in (*) do (
setlocal disableDelayedExpansion
echo G is: %%G
set "_srcp=%%G"
setlocal enableDelayedExpansion
echo _srcp is !_srcp!
set "_newp=!_srcp:ai=_01_!"
echo _newp is: !_newp!
endlocal
endlocal
)
Run Code Online (Sandbox Code Playgroud)
您也可以使用带有双百分比的 CALL 获得所需的结果,但这要慢得多。如果执行几次,速度并不重要,但如果在一个循环中执行数千次,则速度变得非常重要。
@echo off
for /D %%G in (*) do (
setlocal
echo G is: %%G
set "_srcp=%%G"
call echo _srcp is %%_srcp%%
call set "_newp=%%_srcp:ai=_01_%%"
call echo _newp is: %%_newp%%
endlocal
)
Run Code Online (Sandbox Code Playgroud)