我们有一个列出一堆路径的文本文件,以及一个从该文件中读取行的批处理文件。
例如,TargetFolders.txt可能包含以下行:
%ProgramFiles%\Acme\FooBar %VersionNumber%
当然,当我们从文本文件中读取这一行时(使用FOR命令),变量%% I接收实际行文本,使用%符号而不是替换变量值。所以,
SET VersionNumber=7.0
FOR /F "eol=; delims=" %%I IN (TargetFolders.txt) DO (
echo Folder: %%I
)
打印
Folder: %ProgramFiles%\Acme\FooBar %VersionNumber%
如何使其替换实际变量值,以便打印
Folder: C:\Program Files\Acme\FooBar 7.0
答案 0 :(得分:8)
SET VersionNumber=7.0
FOR /F "eol=; delims=" %%I IN (TargetFolders.txt) DO (
for /F "usebackq delims=" %%J in (`echo %%I`) do echo Folder: %%J
)
你去吧。 (这就是你想要的,对吗?)
答案 1 :(得分:5)
简单地添加CALL可以解决您的问题。 (也是你对VersionNumber的定义错了)
SET VersionNumber=7.0
FOR /F "eol=; delims=" %%I IN (TargetFolders.txt) DO (
call echo Folder: %%I
)
但如果您的文件包含&
,>
,<
,|
等不带引号的特殊字符,则会失败。
例如,以下行将失败:
%ProgramFiles%\This&That\ %VersionNumber%
如果引用它将起作用
"%ProgramFiles%\This&That\" %VersionNumber%
CALL也会破坏任何引用的插入符号:"^"
将成为"^^"
最佳解决方案是修改您的文本文件,并将每个%
替换为!
。
!ProgramFiles!\Acme\FooBar !VersionNumber!
!ProgramFiles!\This&That !VersionNumber!
现在,您可以安全地使用延迟扩展来扩展循环中的变量。
setlocal enableDelayedExpansion
SET VersionNumber=7.0
FOR /F "eol=; delims=" %%I IN (TargetFolders.txt) DO (
echo Folder: %%I
)
如果您的文本文件已经保留了!
,则必须对其进行转义。如果^
显示在带有!
的行上,则必须对preserve caret ^^ and exclamation ^! by escaping
caret ^ without exclamation is no problem
进行转义。
alternate method to preserve caret !c! and exclamation !x!
caret ^ without exclamation still no problem
或者,您可以将变量替换为插入符号和感叹号文字
setlocal enableDelayedExpansion
set "x=^!"
set "c=^"
SET VersionNumber=7.0
FOR /F "eol=; delims=" %%I IN (TargetFolders.txt) DO (
echo Folder: %%I
)
然后在批处理中定义变量
{{1}}
答案 2 :(得分:0)
使用更健壮的变体补充现有的有用答案,也正确处理以下嵌入字符:& | < > ^
[1]
:
请注意,为简单起见,我使用字符串来驱动外部循环,其文字值 - 来之后由内循环扩展 - %ProgramFiles%\Acme\FooBar %VersionNumber%
,因为%
实例加倍。
set "VersionNumber=0.7"
for /f "delims=" %%f in ("%%ProgramFiles%%\Acme\FooBar %%VersionNumber%%") do (
for /f "delims=" %%g in ('echo "%%f"') do echo Folder: [%%~g]
)
这会产生类似Folder: [C:\Program Files\Acme\FooBar 0.7]
注意:
for /f
将单引号字符串('...'
)解释为要执行的命令和要捕获的输出; delims=
告诉for
将输出作为一个整体捕获到单个变量中
(虽然可以使用usebackq
并使用`...`
封闭的命令,但在这种情况下这样做没有任何优势。)注意外部循环变量的引用是如何双引号("%%f"
),这是允许值包含所述特殊字符的原因打破echo
命令。
因为输出也会被双引号,~
运算符用于在回显它(%%~g
)时从捕获的值中去除封闭的双引号。
[1]另外处理嵌入式"
实例的解决方案比较棘手:
rem Construct a variable whose value contains all shell metacharacters.
rem % chars. meant to be treated as literals must be doubled (%%)
rem Note the extra " at the end, which appends an unbalanced double quote.
set "var=%%OS%% & %%ba^r | (baz) <mo'>""
rem Embedded " chars. must be escaped as "" (doubling them).
for /f "delims=" %%v in ('echo "%var:"=""%"') do set "expandedVar=%%~v"
rem Note: The resulting variable's value:
rem - can only be echoed *double-quoted*, as the command will otherwise break.
rem - still contains the *doubled* embedded double quotes, which, however,
rem is the escaping that other Microsoft programs expect.
echo "[%expandedVar%]"
这会产生:"[Windows_NT & %ba^r | (baz) <mo'>""]"