Peter は、拡張の遅延の問題をすでに診断しています。ここにもう少し説明があります。
FOR 変数は遅延展開の前に展開されます。そのため、行はset "line=%%B"
最初に値をif ( !production ) {}
に設定しますが、遅延拡張はペアになっていないものを見て、!
それを取り除きます。ペアになっている場合は、その間の変数を展開しようとします。
変数展開の順序の要約を次に示します (実用的ですが、少し不正確です)。
1) 通常展開: 引数 (%1) と変数 (%var%)。引数は変数よりも優先されます。
2) FOR 変数: %%A
3) 遅延展開: !var!
4) SET /A 変数
行がどのように解析および展開されるかについてのより正確な説明については、「Windows コマンド インタープリター (CMD.EXE) はスクリプトをどのように解析するか」を参照してください。
!
遅延展開のオンとオフを切り替えると、リテラルを破損することなく、ループ内で遅延展開を使用できます。これは、CALL 構文を使用するよりも優先されます。これは、より高速で、%
リテラルをいじらず、キャレットを二重引用符で囲まず、引用符で囲まれていない場合でも、すべての有害な文字から保護するためです。
遅延展開を使用すると、コードがはるかに単純で高速になり、信頼性が高くなります。
setlocal disableDelayedExpansion
(FOR /F "tokens=1,* delims=]" %%A in ('"type test.js|find /n /v """') do (
set "line=%%B"
setlocal enableDelayedExpansion
if defined line (
echo(!line:production:false=production:true!
) ELSE echo(
endlocal
)) >test-temp.js
move /Y test-temp.js test.js
endlocal
後者はあいまいなシナリオで失敗する可能性があるため、ECHO(
代わりに使用することに注意してください。ブロック括弧で問題が発生するように見えますが、実際には常に問題なく動作します。ECHO.
ECHO(
上記のコードはまだ使用しないことに注意してください。代わりに、フォクシドライブが彼の答えにあるように、REPL.BATユーティリティを使用します。