内部循环查找和替换[批处理脚本]

时间:2013-06-28 20:02:32

标签: windows for-loop batch-file cmd pattern-matching

以下代码有效, 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%
)

我在这里做错了什么?

2 个答案:

答案 0 :(得分:6)

如果您了解代码使用call set str=%%str:\=%replaceWith%%%的原因,那么您应该能够解决这个问题; - )

解析行时会扩展像%var%这样的语法,并且在一次传递中解析整个带括号的FOR循环。因此%replaceWith%echo %str%将使用您在进入循环之前存在的值。

CALL语句对每次迭代都会进行额外的解析,但这只能部分解决问题。

第一次运行脚本时,您可能只是“ECHO已开启”。 (或关闭)4次。但是,脚本完成后,str的值可能为ggghhhhhreplaceWith.。您没有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!
)

答案 1 :(得分:3)

请为 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
)