我们有一个列出一堆path的文本文件,以及一个从这个文件中读取行的batch file。
例如,TargetFolders.txt可能包含以下行:
%ProgramFiles%\Acme\FooBar %VersionNumber%
当然,当我们从文本文件(使用FOR命令)读取这一行时,variables%%我接收实际的行文本,使用%符号而不是replacevariables值。 所以,
SET VersionNumber=7.0 FOR /F "eol=; delims=" %%I IN (TargetFolders.txt) DO ( echo Folder: %%I )
打印
Folder: %ProgramFiles%\Acme\FooBar %VersionNumber%
如何使其取代实际的variables值,以便打印
Folder: C:\Program Files\Acme\FooBar 7.0
?
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 )
你走了 (这是你想要的,对吧?)
只需添加一个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] :
请注意,为了简单起见,我使用了一个字符串来驱动外部循环,由于内部循环后面的内部循环扩展了%
实例,所以它是%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=
通过一个变量来捕获整个输出。 usebackq
来代替`...`
-enclosed命令,但在这种情况下这样做没有任何优势。) 注意对外循环变量的引用是如何用双引号 ( "%%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'>""]"