【发布时间】:2012-01-21 13:17:12
【问题描述】:
我已经编写了巨大的 MS DOS 批处理文件。要测试这个批处理文件,我只需要执行一些行并希望隐藏/注释掉剩余的。
我有一些以:: 开头的现有注释行,因此我不能再使用::,因为它会打乱所有cmets。
我该如何解决这个问题?
【问题讨论】:
标签: batch-file comments dos multiline
我已经编写了巨大的 MS DOS 批处理文件。要测试这个批处理文件,我只需要执行一些行并希望隐藏/注释掉剩余的。
我有一些以:: 开头的现有注释行,因此我不能再使用::,因为它会打乱所有cmets。
我该如何解决这个问题?
【问题讨论】:
标签: batch-file comments dos multiline
您可以使用goto 跳过代码。
goto comment
...skip this...
:comment
【讨论】:
REM 行作为注释行,这使得输出模糊
如果您想在每行的开头添加 REM 而不是使用 GOTO,您可以使用 Notepad++ 按照以下步骤轻松完成:
重复步骤以取消注释
【讨论】:
break||(
code that cannot contain non paired closing bracket
)
虽然goto 解决方案是一个不错的选择,但它不会工作within brackets(包括 FOR 和 IF 命令)。但这会。尽管您应该小心 FOR 和 IF 命令的右括号和无效语法,因为它们将被解析。
更新
dbenham's 答案中的更新给了我一些想法。
首先 - 在两种不同的情况下,我们可能需要多行 cmets - 在不能使用 GOTO 的括号上下文中和在它之外。
如果存在阻止代码执行的条件,我们可以在括号上下文中使用另一个括号。尽管仍然会解析代码
并且会检测到一些语法错误(FOR,IF,不正确的右括号,错误的参数扩展..)。所以如果可能的话最好使用GOTO。
虽然不可能创建用作标签的宏/变量 - 但可以将宏用于括号的 cmets。仍然可以使用两个技巧来制作 GOTO
cmets 更对称,更令人愉悦(至少对我而言)。为此,我将使用两个技巧 - 1) 您可以在标签前放置一个符号,然后 goto 仍然可以
找到它(我不知道为什么会这样。我猜它正在寻找驱动器)。 2)你可以放一个:
在变量名称的末尾,将不会触发替换/子字符串功能(即使在启用的扩展名下)。 Wich 与括号 cmets 的宏结合可以
让这两种情况看起来几乎一样。
以下是示例(按照我最喜欢的顺序):
带方括号:
@echo off
::GOTO comment macro
set "[:=goto :]%%"
::brackets comment macros
set "[=rem/||(" & set "]=)"
::testing
echo not commented 1
%[:%
multi
line
comment outside of brackets
%:]%
echo not commented 2
%[:%
second multi
line
comment outside of brackets
%:]%
::GOTO macro cannot be used inside for
for %%a in (first second) do (
echo first not commented line of the %%a execution
%[%
multi line
comment
%]%
echo second not commented line of the %%a execution
)
带大括号:
@echo off
::GOTO comment macro
set "{:=goto :}%%"
::brackets comment macros
set "{=rem/||(" & set "}=)"
::testing
echo not commented 1
%{:%
multi
line
comment outside of brackets
%:}%
echo not commented 2
%{:%
second multi
line
comment outside of brackets
%:}%
::GOTO macro cannot be used inside for loop
for %%a in (first second) do (
echo first not commented line of the %%a execution
%{%
multi line
comment
%}%
echo second not commented line of the %%a execution
)
带括号:
@echo off
::GOTO comment macro
set "(:=goto :)%%"
::brackets comment macros
set "(=rem/||(" & set ")=)"
::testing
echo not commented 1
%(:%
multi
line
comment outside of brackets
%:)%
echo not commented 2
%(:%
second multi
line
comment outside of brackets
%:)%
::GOTO macro cannot be used inside for loop
for %%a in (first second) do (
echo first not commented line of the %%a execution
%(%
multi line
comment
%)%
echo second not commented line of the %%a execution
)
powershell 和 C 样式之间的混合(< 不能使用,因为重定向具有更高的优先级。* 因为%* 而不能使用):
@echo off
::GOTO comment macro
set "/#:=goto :#/%%"
::brackets comment macros
set "/#=rem/||(" & set "#/=)"
::testing
echo not commented 1
%/#:%
multi
line
comment outside of brackets
%:#/%
echo not commented 2
%/#:%
second multi
line
comment outside of brackets
%:#/%
::GOTO macro cannot be used inside for loop
for %%a in (first second) do (
echo first not commented line of the %%a execution
%/#%
multi line
comment
%#/%
echo second not commented line of the %%a execution
)
强调这是一条评论(认为它不是那么短):
@echo off
::GOTO comment macro
set "REM{:=goto :}REM%%"
::brackets comment macros
set "REM{=rem/||(" & set "}REM=)"
::testing
echo not commented 1
%REM{:%
multi
line
comment outside of brackets
%:}REM%
echo not commented 2
%REM{:%
second multi
line
comment outside of brackets
%:}REM%
::GOTO macro cannot be used inside for
for %%a in (first second) do (
echo first not commented line of the %%a execution
%REM{%
multi line
comment
%}REM%
echo second not commented line of the %%a execution
)
【讨论】:
rem.||( 或rem^ (。意图更清晰一些。请参阅我的更新答案。
rem/||( 。如果在同一目录中有一个名为rem 的文件,使用rem 会产生错误。
另一种选择是将不需要的行包含在一个永远不会为真的 IF 块中
if 1==0 (
...
)
当然,if 块中的任何内容都不会被执行,但会被解析。所以你不能有任何无效的语法。此外,注释不能包含),除非它被转义或引用。由于这些原因,公认的 GOTO 解决方案更可靠。 (GOTO 方案也可能更快)
2017 年 9 月 19 日更新
这是pdub's GOTO solution 的外观增强功能。我定义了一个简单的环境变量“宏”,它使 GOTO 注释语法更好地自我记录。虽然通常建议 :labels 在批处理脚本中是唯一的,但在同一个批处理脚本中嵌入多个这样的 cmets 确实是可以的。
@echo off
setlocal
set "beginComment=goto :endComment"
%beginComment%
Multi-line comment 1
goes here
:endComment
echo This code executes
%beginComment%
Multi-line comment 2
goes here
:endComment
echo Done
或者您可以使用npocmaka's solution 的这些变体之一。使用 REM 而不是 BREAK 使意图更加清晰。
rem.||(
remarks
go here
)
rem^ ||(
The space after the caret
is critical
)
【讨论】:
rem/||(…),这将是safe,而不是rem.…
只想提一下pdub's GOTO solution 不完全正确,以防 :comment 标签多次出现。我以this question修改代码为例。
@ECHO OFF
SET FLAG=1
IF [%FLAG%]==[1] (
ECHO IN THE FIRST IF...
GOTO comment
ECHO "COMMENT PART 1"
:comment
ECHO HERE AT TD_NEXT IN THE FIRST BLOCK
)
IF [%FLAG%]==[1] (
ECHO IN THE SECOND IF...
GOTO comment
ECHO "COMMENT PART"
:comment
ECHO HERE AT TD_NEXT IN THE SECOND BLOCK
)
输出将是
IN THE FIRST IF...
HERE AT TD_NEXT IN THE SECOND BLOCK
ECHO HERE AT TD_NEXT IN THE FIRST BLOCK 被跳过。
【讨论】:
@jeb
而且使用这个之后,stderr 似乎无法访问了
不,试试这个:
@echo off 2>Nul 3>Nul 4>Nul
ben ali
mubarak 2>&1
gadeffi
..next ?
echo hello Tunisia
pause
但它为什么有效?
对不起,我用法语回答问题:
( la redirection par 3> est spécial car elle persiste, on va l'utiliser pour capturer le flux des erreurs 2> est on va le transformer en un flux persistant à l'ade de 3> ceci va nous permettre d'avoir une gestion des erreur pour tout notre environment de script..par la suite si on veux recuperer le flux 'stderr' il faut faire une autre redirection du handle 2> au handle 1> qui n'est autre que la控制台..)
【讨论】:
试试这个:
@echo off 2>Nul 3>Nul 4>Nul
ben ali
mubarak
gadeffi
..next ?
echo hello Tunisia
pause
【讨论】: