1

我有这个小片段替换production:falseproduction: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

彼得已经诊断出延迟扩张的问题。这里有一点解释。

FOR 变量在延迟扩展之前扩展。因此,该行set "line=%%B"首先将值设置为if ( !production ) {},但延迟扩展会看到未配对!并将其剥离。如果它是配对的,它会尝试扩展其间的变量。

这里总结一下变量展开的顺序(实用,但有点不精确):

1)正常扩展:参数(%1)和变量(%var%)。参数优先于变量。

2)对于变量:%%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(看起来它会导致圆括号出现问题,但它实际上总是可以正常工作。

请注意,我仍然不会使用上面的代码。相反,我会像 foxidrive 在他的回答中那样使用 REPL.BAT 实用程序。

于 2013-10-17T00:45:57.613 回答
2

repl.bat这是一个健壮的方法,并使用从 - http://www.dostips.com/forum/viewtopic.php?f=3&t=3855调用的帮助程序批处理文件

放在repl.bat与批处理文件相同的文件夹中。

@echo off
type "test.js"|repl "production:false" "production:true" >"test-temp.js"
于 2013-10-16T16:08:17.687 回答
2

你可能已经delayedexpansion调用了。

针对您提供的单行数据运行您的代码段(这是您给我们的全部内容)只是逐字复制了数据行。

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 回答