如何替换 Windows 批处理文件中的变量内容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4367297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to substitute variable contents in a Windows batch file
提问by GKelly
I'm writing a simple script to substitute text in an environment variable with other text. The trouble I get is with the substituted or substituted text being pulled from other variables
我正在编写一个简单的脚本来用其他文本替换环境变量中的文本。我遇到的麻烦是从其他变量中提取替换或替换的文本
SET a=The fat cat
ECHO %a%
REM Results in 'The fat cat'
ECHO %a:fat=thin%
REM Results in 'The thin cat'
Works fine (output is 'The fat cat' and 'The thin cat'
工作正常(输出是“肥猫”和“瘦猫”
However, if 'fat' or 'thin' are in variables, it doesn't work
但是,如果 'fat' 或 'thin' 在变量中,则不起作用
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!'
I know this can be done as I've seen it in blogs before, but I never saved the link to the blogs.
我知道这可以像我以前在博客中看到的那样完成,但我从未保存到博客的链接。
Anyone have any ideas?
谁有想法?
PS. I'm running the scripts on Windows 7
附注。我在 Windows 7 上运行脚本
PPS. I know this is easier in Perl/Python/other script language of choice, but I just want to know why something that should be easy is not immediately obvious.
聚苯乙烯。我知道这在 Perl/Python/其他选择的脚本语言中更容易,但我只是想知道为什么应该很容易的东西不是很明显。
PPPS. I've also tried the scripts with delayed expansion explicitly turned on
购买力平价。我还尝试了显式打开延迟扩展的脚本
SETLOCAL enabledelayedexpansion
This makes no difference.
这没什么区别。
采纳答案by Paul Tomasi
Please try the following:
请尝试以下操作:
Copy and paste the code into Notepad and save it as a batch file.
将代码复制并粘贴到记事本中,并将其另存为批处理文件。
@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%]
I hope you're convinced!
我希望你被说服!
回答by Zuzu Corneliu
Use CALL. Put the following in a batch script and run it:
使用呼叫。将以下内容放入批处理脚本中并运行它:
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
As stated here, we use the fact that:
正如此处所述,我们使用以下事实:
CALL internal_cmd
...
internal_cmdRun an internal command, first expanding any variables in the argument.
调用internal_cmd
...
internal_cmd运行内部命令,首先扩展参数中的所有变量。
In our case internal_cmdis initially set a=%%a:%b%^=%c%%%.
在我们的例子中,internal_cmd最初设置为 a=%%a:%b%^=%c%%%。
After expansion internal_cmdbecomes set a=%a:fat=thin%.
扩展internal_cmd 后变为set a=%a:fat=thin%。
Thus, in our case running
因此,在我们的例子中运行
call set a=%%a:%b%^=%c%%%
调用集 a=%%a:%b%^=%c%%%
is equivalentto running:
是等同于运行:
set a=%a:fat=thin%.
设置 a=%a:fat=thin%。
回答by Paul Tomasi
And... How about this?
还有……这个怎么样?
@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%]
Nifty eh?
漂亮吧?
回答by Ferruccio
The problem with:
问题在于:
echo %a:%c%=thin%
is that it tries to expand two variables: a:
and =thin
with a c
constant string between them.
是它试图扩展两个变量:a:
并在它们之间=thin
使用一个c
常量字符串。
Try this:
尝试这个:
echo echo ^%a:%c%=thin^% | cmd
The first command outputs:
第一个命令输出:
echo %a:fat=thin%
which is piped into a second command shell for evaluation.
它通过管道传输到第二个命令外壳进行评估。
回答by naren
Recently I came accross the same situation..As said earlier, I used like below and worked...
最近我遇到了同样的情况......如前所述,我使用如下并工作......
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
Output :
输出 :
\log\process
It worked..!!
有效..!!
回答by Kevin Fegan
I try to avoid using SETLOCAL enabledelayedexpansion ... ENDLOCAL
all (or nearly all) the time, because usually I want to set or modify a few variables and I want the new values to be available in other areas of the script or after the batch script ends (SETLOCAL|ENDLOCAL will forget about any new variables or changes to variables in the "SETLOCAL" part of the script. Sometimes that's handy, but for me I find it's usually not.
我尽量避免使用SETLOCAL enabledelayedexpansion ... ENDLOCAL
所有(或几乎所有)时间,因为通常我想设置或修改一些变量,并且我希望新值在脚本的其他区域或批处理脚本结束后可用 (SETLOCAL|ENDLOCAL会忘记脚本的“SETLOCAL”部分中的任何新变量或对变量的更改。有时这很方便,但对我来说通常不是。
Currently I use the method described by @Zuzel, but before I knew about that method, I used to use this, which is very similar (but looks a bit more complicated):
目前我使用@Zuzel描述的方法,但在我知道该方法之前,我曾经使用过这个,它非常相似(但看起来有点复杂):
for /F "usebackq delims=" %%f in (`echo set "a=^%a:%b%=%c%^%"`) do @%%f
example script:
示例脚本:
@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
the output from running the script:
运行脚本的输出:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using for:
after for: "The thin cat"
I like this method because you can call external programs (or internal commands) using modified variables and also capture and process the output of the command (line by line).
我喜欢这种方法,因为您可以使用修改后的变量调用外部程序(或内部命令),还可以捕获和处理命令的输出(逐行)。
But, Zuzel's method is simpler and cleaner for most situations, including the one you described.
但是,Zuzel 的方法在大多数情况下更简单、更清晰,包括您描述的那种。
Note:
笔记:
Both of these methods (and also SETLOCAL enabledelayedexpansion ... ENDLOCAL
, of course), only work correctly if run from within a batch script. If you try to use either of these two methods ("call" or "for") directly in a command prompt window, you will get something different from what the output was running from a script.
这两种方法(SETLOCAL enabledelayedexpansion ... ENDLOCAL
当然还有 )只有在从批处理脚本中运行时才能正常工作。如果您尝试在命令提示符窗口中直接使用这两种方法(“call”或“for”)中的任何一种,您将获得与从脚本运行的输出不同的东西。
For example, run this as a script:
例如,将其作为脚本运行:
@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%")
the output from running the script:
运行脚本的输出:
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")
Now, run those commands directly in a command prompt window:
现在,直接在命令提示符窗口中运行这些命令:
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:\>
examine the before and after output lines from the command prompt window:
从命令提示符窗口检查之前和之后的输出行:
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")
Notice that the substitutions are made correctly, but also notice that with running these commands directly in the command prompt window, it adds a set of "%" (percent signs) before and after the expected value each time the substitution is made. So, it makes it difficult to test any of these methods directly in the command prompt window.
请注意,替换是正确进行的,但也请注意,在命令提示符窗口中直接运行这些命令时,每次进行替换时,它都会在预期值之前和之后添加一组“%”(百分号)。因此,很难直接在命令提示符窗口中测试这些方法中的任何一种。
回答by mosh
:: Use perl on %var% =~ s/$old/$new/
:: 在 %var% =~ s/$old/$new/ 上使用 perl
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%
Output:
输出:
before=The fat cat
after=The thin cat