【问题标题】:Find and Replace inside for loop [batch script]在 for 循环中查找和替换 [批处理脚本]
【发布时间】:2013-06-26 16:52:15
【问题描述】:
以下代码有效,echo test.test
set replaceWith=.
set str="test\test"
call set str=%%str:\=%replaceWith%%%
echo %str%
但是,下面的代码回显 ggg.hhhhh 4 次。
SET SERVICE_LIST=(aaa\bbb ccc\dddd eeee\fffff ggg\hhhhh)
for %%i in %SERVICE_LIST% do (
set replaceWith=.
set str="%%i"
call set str=%%str:\=%replaceWith%%%
echo %str%
)
我在这里做错了什么?
【问题讨论】:
标签:
windows
for-loop
batch-file
cmd
pattern-matching
【解决方案1】:
如果您了解您的代码为什么使用call set str=%%str:\=%replaceWith%%%,那么您应该能够弄清楚这一点;-)
像%var% 这样的语法在解析行时被扩展,并且你的整个带括号的 FOR 循环在一次解析中被解析。所以%replaceWith% 和echo %str% 将使用你进入循环之前存在的值。
CALL 语句对每次迭代都进行额外的解析,但这只能部分解决问题。
第一次运行脚本时,您可能刚刚得到“ECHO 已开启”。 (或关闭)4 次。但是,脚本完成后str 的值可能是ggghhhhh 而replaceWith 是.。您没有 SETLOCAL,因此当您再次运行时,现在在循环开始之前设置了这些值。第二次运行后,您可能会得到ggghhhhh 4 次。然后从那时起,每次运行脚本都会得到ggg.hhhhh 4 次。
您可以通过在 ECHO 语句中使用 CALL 并在循环之前移动 replaceWith 的分配来获得所需的结果。
@echo off
setlocal
SET SERVICE_LIST=(aaa\bbb ccc\dddd eeee\fffff ggg\hhhhh)
set "replaceWith=."
for %%i in %SERVICE_LIST% do (
set str="%%i"
call set str=%%str:\=%replaceWith%%%
call echo %%str%%
)
但是有一个更好的方法——延迟扩展
@echo off
setlocal enableDelayedExpansion
SET "SERVICE_LIST=aaa\bbb ccc\dddd eeee\fffff ggg\hhhhh"
set "replaceWith=."
for %%i in (%SERVICE_LIST%) do (
set str="%%i"
set str=!str:\=%replaceWith%!
echo !str!
)
【解决方案2】:
请准备一本Windows 命令外壳脚本语言的教科书,然后试试这个:
@ECHO OFF &SETLOCAL
SET "SERVICE_LIST=(aaa\bbb ccc\dddd eeee\fffff ggg\hhhhh)"
for /f "delims=" %%i in ("%SERVICE_LIST%") do (
set "replaceWith=."
set "str=%%i"
SETLOCAL ENABLEDELAYEDEXPANSION
call set "str=%%str:\=!replaceWith!%%"
echo !str!
ENDLOCAL
)