2 つのスクリプトのどちらも、あなたが思っているようなことをするとは思いません (具体的には、2 番目のスクリプトは、最初のスクリプトの後に実行するという理由だけでそのように機能します)。
なぜそのように振る舞うのですか?
注意すべき重要なことは、遅延変数展開がオンになっていない限り、変数はそのコマンドが実行される前に各コマンドに対して評価されるということです。括弧内のコマンド ブロック全体が 1 つのコマンドと見なされる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%
これは 1 つのコマンドにすぎないため、変数は実行前に 1 回だけ展開されます (特に、 の後SET
と の前では展開されませんECHO
)。
これは、スクリプトでも発生します。はブロック内%variable%
で設定およびエコーされるため、 はECHO
実際%variable%
にはブロックに入る前の値で動作するため、「現在の」値は表示されません。
修正方法は?
遅延変数展開の問題を解決する
これには 2 つの方法があります。簡単な方法は、遅延変数展開を有効にし、代わりに次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
a を使用してGOTO
、「成功」ブランチ内の以前のコードをスキップします。
SET foo=
ECHO foo = %foo%
IF NOT 1==1 GOTO :proceed
SET foo=bar
ECHO foo = %foo%
:proceed
上記のスクリプトは、次の出力も行います。
foo =
foo = bar
あなたの例にソリューションを適用する
2 つのアプローチは、次のいずれかに変換されます。
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