我有一个小代码片段用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 ) {}
事情是,“!”也被上述命令删除。知道怎么回事?
答案 0 :(得分: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
答案 1 :(得分: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"
答案 2 :(得分:2)
FOR变量在延迟扩展之前扩展。因此,行set "line=%%B"
首先将值设置为if ( !production ) {}
,但是延迟扩展会看到未配对的!
并将其删除。如果它是配对的,它会尝试在两者之间扩展变量。
以下是变量扩展顺序的总结(实用,但有点不精确):
1)正常扩展:参数(%1)和变量(%var%)。参数优先于变量。
2)FOR变量:%% A
3)延迟扩展:!var!
4)SET / A变量
有关如何解析和扩展行的详细说明,请参阅How does the Windows Command Interpreter (CMD.EXE) parse scripts。
如果您打开和关闭延迟扩展,可以在循环中使用延迟扩展而不会破坏!
文字。这比使用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(
看起来会导致块括号出现问题,但实际上它总是没有任何问题。
请注意,我仍然不会使用上面的代码。相反,我会在他的回答中使用REPO2.BAT实用程序作为foxidrive。