5

以下代码有效,echo test.test

set replaceWith=.
set str="test\test"
call set str=%%str:\=%replaceWith%%%
echo %str%

但是,下面的代码echo ggg.hhhhh all the 4 times

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%
)

我在这里做错了什么?

4

2 回答 2

7

如果您了解您的代码使用的原因call set str=%%str:\=%replaceWith%%%,那么您应该能够弄清楚这一点;-)

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

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

第一次运行脚本时,您可能刚刚得到“ECHO 已开启”。(或关闭)4 次。但是, 的值str可能是ggghhhhh并且replaceWith.在脚本完成之后。您没有 SETLOCAL,因此当您再次运行时,现在在循环开始之前设置了这些值。第二次运行后,您可能会获得ggghhhhh4 次。然后从那时起,每次运行脚本都会获得ggg.hhhhh4 次。

您可以通过在 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!
)
于 2013-06-28T21:29:05.420 回答
6

请有一本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
)
于 2013-06-28T21:24:45.493 回答