我认为这两个脚本中的任何一个都不会像您认为的那样做(具体来说,第二个脚本之所以这样工作,只是因为您在第一个脚本之后运行它)。
为什么它会这样?
需要注意的重要一点是,除非打开延迟变量扩展,否则将在执行该命令之前为每个命令评估变量。这在使用时尤其重要IF
,因为括号内的整个命令块被视为一个命令。
为了显示:
SET foo=
ECHO foo = %foo%
IF 1==1 (
SET foo=bar
ECHO foo = %foo%
)
上面的脚本将输出:
foo =
foo =
原因是条件相当于
IF 1==1 SET foo=bar && ECHO foo = %foo%
这只是一个命令,因此变量在运行之前只扩展一次(特别是,它们不会在 the 之后SET
和之前扩展ECHO
)。
这也是您的脚本中发生的情况。因为在块内%variable%
设置和回显,ECHO
实际操作的是%variable%
在进入块之前的值,因此您看不到“当前”值。
如何解决?
解决延迟变量扩展的问题
有两种方法可以解决这个问题。最直接的一种是启用延迟变量扩展,SETLOCAL
然后使用语法!var!
而不是引用变量%var%
:
SETLOCAL ENABLEDELAYEDEXPANSION
SET foo=
ECHO foo = !foo!
IF 1==1 (
SET foo=bar
ECHO foo = !foo!
)
上面的脚本将输出:
foo =
foo = bar
通过分解命令块来解决问题
还有另一种方法可以做到这一点:请记住,在执行每个命令(或块)之前,变量会被扩展一次。SET
因此,如果您希望在和之间发生扩展ECHO
,可以通过分解块来实现。您可以通过反转测试NOT
并使用 aGOTO
跳过“成功”分支中较早的代码来做到这一点:
SET foo=
ECHO foo = %foo%
IF NOT 1==1 GOTO :proceed
SET foo=bar
ECHO foo = %foo%
:proceed
上面的脚本也会输出:
foo =
foo = bar
将解决方案应用于您的示例
这两种方法转化为:
SETLOCAL ENABLEDELAYEDEXPANSION
IF "%condition%" == "1" (
FOR /F "tokens=1,2,3,4* delims= " %%a in (output.txt) DO SET variable=%%a
ECHO !variable!
)
或这个:
IF NOT "%condition%" == "1" GOTO :proceed
FOR /F "tokens=1,2,3,4* delims= " %%a in (output.txt) DO SET variable=%%a
ECHO %variable%
:proceed