如何在Windowsbatch file中replacevariables内容

我正在写一个简单的脚本来replace其他文本的环境variables中的文本。 我得到的麻烦是取代或replace的文本从其他variables拉

SET a=The fat cat ECHO %a% REM Results in 'The fat cat' ECHO %a:fat=thin% REM Results in 'The thin cat' 

工作正常(输出是“肥猫”和“瘦猫”

但是,如果“胖”或“瘦”是variables,它不起作用

 SET b=fat ECHO %a:%c%=thin% REM _Should_ give 'The thin cat'. REM _Actually_ gives '%a:fat=thin%' (the %c% is evaluated, but no further). REM using delayed evaluation doesn't make any difference either ECHO !a:%c%=thin! REM Actual output is now '!a:fat=thin!' 

我知道这可以做,因为我曾经在博客中看到过,但我从来没有保存链接到博客。

有人有主意吗?

PS。 我在Windows 7上运行脚本

PPS。 我知道在Perl / Python /其他脚本语言中这是比较容易的,但我只是想知道为什么应该是容易的事情不是马上就显而易见的。

购买力平价。 我也尝试了明确打开延迟扩展的脚本

 SETLOCAL enabledelayedexpansion 

这没有什么区别。

Solutions Collecting From Web of "如何在Windowsbatch file中replacevariables内容"

请尝试以下操作:

将代码复制并粘贴到记事本中,并将其保存为批处理文件。

  @echo off setlocal enabledelayedexpansion set str=The fat cat set f=fat echo. echo f = [%f%] echo. echo str = [%str%] set str=!str:%f%=thin! echo str:f=thin = [%str%] 

我希望你确信!

使用CALL 。 将以下内容放在批处理脚本中并运行它:

 set a=The fat cat set b=fat set c=thin REM To replace "%b%" with "%c%" in "%a%", we can do: call set a=%%a:%b%^=%c%%% echo %a% pause 

如此处所述,我们使用以下事实:

调用internal_cmd

internal_cmd运行一个内部命令, 首先展开参数中的任何变量

在我们的例子中, internal_cmd最初被设置为a = %% a:%b%^ =%c %%%

扩展后internal_cmd变成a =%a:fat = thin%

因此,在我们的情况下运行

call set a = %% a:%b%^ =%c %%%

相当于运行:

设置a =%a:fat = thin%

问题在于:

 echo %a:%c%=thin% 

是它试图扩展两个变量: a:=thin ,它们之间有一个c常量字符串。

尝试这个:

 echo echo ^%a:%c%=thin^% | cmd 

第一个命令输出:

 echo %a:fat=thin% 

将其传送到第二个命令外壳进行评估。

而…这个怎么样?

 @echo off setlocal enabledelayedexpansion set str=The fat cat set f=fat set t=thin echo. echo f = [%f%] echo t = [%t%] echo. echo str = [%str%] set str=!str:%f%=%t%! echo str:f=t = [%str%] 

漂亮的呃?

最近我遇到了同样的情况。如前所述,我用下面的方式工作…

 set filearg=C:\data\dev\log\process set env=C:\data\dev REM I wanted \log\process as output SETLOCAL enabledelayedexpansion set str2=!filearg:%env%=! echo Output : %str2% echo. endlocal 

输出:

 \log\process 

有效..!!

我尝试避免使用SETLOCAL enabledelayedexpansion ... ENDLOCAL所有(或几乎所有)时间,因为通常我想要设置或修改一些变量,我希望新的值在脚本的其他区域或批处理后可用脚本结束(SETLOCAL | ENDLOCAL将忘记脚本的“SETLOCAL”部分中的任何新变量或对变量的更改。有时这很方便,但对于我来说我通常不会。

目前我使用@Zuzel描述的方法,但是在我知道这个方法之前,我曾经使用过这个,它非常相似(但看起来更复杂一些):

 for /F "usebackq delims=" %%f in (`echo set "a=^%a:%b%=%c%^%"`) do @%%f 

示例脚本:

 @echo off set a=The fat cat set b=fat set c=thin @echo. @echo before: "%a%" @echo replace "%b%" with "%c%" in "%a%" using for: for /F "usebackq delims=" %%f in (`echo set "a=%%a:%b%=%c%%%"`) do @%%f @echo after for: "%a%" goto :EOF 

运行脚本的输出:

 before: "The fat cat" replace "fat" with "thin" in "The fat cat" using for: after for: "The thin cat" 

我喜欢这种方法,因为您可以使用修改的变量调用外部程序(或内部命令),并捕获并处理命令的输出(逐行)。

但是,祖泽尔的方法在大多数情况下更简单,更清洁,包括你所描述的方法。

注意:

这两种方法(当然还有SETLOCAL enabledelayedexpansion ... ENDLOCAL )只有在批处理脚本中运行时才能正常工作。 如果您尝试在命令提示符窗口中直接使用这两种方法(“call”或“for”),您将得到与脚本中输出内容不同的内容。

例如,将其作为脚本运行:

 @echo off set a=The fat cat set b=fat set c=thin set d=calico set e=sleepy @echo. @echo before: "%a%" @echo. @echo replace "%b%" with "%c%" in "%a%" using call: call set a=%%a:%b%=%c%%% @echo after call: "%a%" ("%b%" to "%c%") @echo. @echo replace "%c%" with "%d%" in "%a%" using for: for /F "usebackq delims=" %%f in (`echo set "a=%%a:%c%=%d%%%"`) do @%%f @echo after for: "%a%" ("%c%" to "%d%") @echo. @echo replace "%d%" with "%e%" in "%a%" using call: call set a=%%a:%d%=%e%%% @echo after call: "%a%" ("%d%" to "%e%") 

运行脚本的输出:

 before: "The fat cat" replace "fat" with "thin" in "The fat cat" using call: after call: "The thin cat" ("fat" to "thin") replace "thin" with "calico" in "The thin cat" using for: after for: "The calico cat" ("thin" to "calico") replace "calico" with "sleepy" in "The calico cat" using call: after call: "The sleepy cat" ("calico" to "sleepy") 

现在,直接在命令提示符窗口中运行这些命令:

 c:\> c:\>set a=The fat cat c:\>set b=fat c:\>set c=thin c:\>set d=calico c:\>set e=sleepy c:\> c:\>@echo. c:\>@echo before: "%a%" before: "The fat cat" c:\>@echo. c:\> c:\>@echo replace "%b%" with "%c%" in "%a%" using call: replace "fat" with "thin" in "The fat cat" using call: c:\>call set a=%%a:%b%=%c%%% c:\>@echo after call: "%a%" ("%b%" to "%c%") after call: "%The thin cat%" ("fat" to "thin") c:\> c:\>@echo. c:\>@echo replace "%c%" with "%d%" in "%a%" using for: replace "thin" with "calico" in "%The thin cat%" using for: c:\>for /F "usebackq delims=" %f in (`echo set "a=%%a:%c%=%d%%%"`) do @%f c:\>@echo after for: "%a%" ("%c%" to "%d%") after for: "%%The calico cat%%" ("thin" to "calico") c:\> c:\>@echo. c:\>@echo replace "%d%" with "%e%" in "%a%" using call: replace "calico" with "sleepy" in "%%The calico cat%%" using call: c:\>call set a=%%a:%d%=%e%%% c:\>@echo after call: "%a%" ("%d%" to "%e%") after call: "%%%The sleepy cat%%%" ("calico" to "sleepy") c:\> 

从命令提示符窗口中检查输出行之前和之后:

 before: "The fat cat" replace "fat" with "thin" in "The fat cat" using call: after call: "%The thin cat%" ("fat" to "thin") replace "thin" with "calico" in "%The thin cat%" using for: after for: "%%The calico cat%%" ("thin" to "calico") replace "calico" with "sleepy" in "%%The calico cat%%" using call: after call: "%%%The sleepy cat%%%" ("calico" to "sleepy") 

请注意,替换是正确的,但也要注意,通过直接在命令提示符窗口中运行这些命令,它会在每次进行替换时在期望值之前和之后添加一组“%”(百分号)。 因此,在命令提示符窗口中直接测试这些方法是很困难的。

::使用perl%var%=〜s / $ old / $ new /

 set var=The fat cat set old=fat set new=thin ECHO before=%var% for /f "delims=" %%m in ('echo %var% ^|perl -pe "s/%old%/%new%/" ') do set var=%%m ECHO after=%var% 

输出:

 before=The fat cat after=The thin cat