1

に置き換えるこの小さなスニペットがproduction:falseありproduction:trueます。

(FOR /F "tokens=1,* delims=]" %%A in ('"type test.js|find /n /v """') do (

    set "line=%%B"

    if defined line (
        call set "line=echo.%%line:production:false=production:true%%"
        FOR /F "delims=" %%X in ('"echo."%%line%%""') do %%~X
    ) ELSE echo.

)) >test-temp.js

move /Y test-temp.js test.js

ここまでは順調ですが、test.js では次のように記述されています。

if ( !production ) {}

問題は、「!」です。上記のコマンドでも削除されます。どのように起こるのですか?

4

3 に答える 3

2

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ユーティリティを使用します。

于 2013-10-17T00:45:57.613 に答える
2

あなたはおそらくdelayedexpansion呼び出しました。

提供されたデータの 1 行に対してスニペット (これだけで十分です) を実行すると、データ行がそのまま再現されます。

delayedexpansion!あなたが説明したように消えました。


修正するには (delayedexpansion有効に

SETLOCAL DISABLEDELAYEDEXPANSION
(FOR /F "tokens=1,* delims=]" %%A in ('"type q19406461.txt|find /n /v """') do (
    set "line=%%B"

    if defined line (
             call set "line=echo.%%line:production:false=production:true%%"
             FOR /F "delims=" %%X in ('"echo."%%line%%""') do %%~X
    ) ELSE echo.

)) >test-temp.js
ENDLOCAL
于 2013-10-16T14:56:25.093 に答える