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

sEl*_*yan 2 windows for-loop cmd batch-file pattern-matching

以下代码有效,echo test.test

set replaceWith=.
set str="test\test"
call set str=%%str:\=%replaceWith%%%
echo %str%
Run Code Online (Sandbox Code Playgroud)

但是,下面的代码回显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%
)
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

dbe*_*ham 6

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

语法喜欢%var%当行被解析,并为循环整个括号内的一通被解析扩大.因此%replaceWith%,echo %str%将使用您进入循环之前存在的值.

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

第一次运行脚本时,您可能只是"ECHO已开启".(或关闭)4次.然而,价值str大概是ggghhhhhreplaceWith.剧本完成之后.您没有SETLOCAL,因此当您再次运行时,现在会在循环开始之前设置值.你第二次跑完后你可能有ggghhhhh4次.然后从那时起,每次运行脚本时都会得到ggg.hhhhh4次.

您可以通过将CALL与ECHO语句一起使用,并在循环之前移动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%%
)
Run Code Online (Sandbox Code Playgroud)

但有更好的方法 - 推迟扩张

@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!
)
Run Code Online (Sandbox Code Playgroud)


End*_*oro 5

请准备一本有关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
)
Run Code Online (Sandbox Code Playgroud)