在DOS批处理文件中注释多行


98

我写了巨大的MS DOS批处理文件。要测试此批处理文件,我只需要执行一些行,并希望隐藏/注释剩余的行。

我有一些现有的注释行开头,::因此我不能再使用::了,因为它会打乱所有注释。

我怎么解决这个问题?

Answers:


182

您可以使用goto跳过代码。

goto comment
...skip this...
:comment

11
+1:为此使用“ goto”很有趣,并且有效!
rap-2-h

1
我认为有趣的是,命令行中没有真正的注释定义,我只是不能接受REM行作为注释行,这使输出变得晦涩
mkb 17/10 / 25,4

125

如果要在每行的开头添加REM而不是使用GOTO,则可以按照以下步骤使用Notepad ++轻松完成此操作:

  1. 选择线段
  2. 按Ctrl-Q

重复步骤以取消注释


6
不错的提示。使它更清洁。
毒液

1
哇,不知道notepad ++有这么好的功能!实际上,我真的很想念它,因为我习惯于在Eclipse中使用Ctrl + 7。投票数达到42 ;)
罗丹妮(Danny Lo

1
那取消评论呢?在该快捷方式中,可以取消注释整个块。
Bhaskar Singh'9

2
@BhaskarSingh从Notepad ++ 7.5.6开始,您只需突出显示已注释的文本即可。执行“ Ctrl + Q”,它将取消注释
CreativiTimothy

如果您的大脑经常像我的一样虚弱Ctrl-Q,请点击Notepad++Edit -> Comment/Uncomment
Timo

13
break||(
 code that cannot contain non paired closing bracket
)

虽然该goto解决方案是一个不错的选择,但它不能在方括号内使用(包括FOR和IF命令),但是可以。尽管您应注意不要用括号括起来以及FORand IF命令的无效语法,因为它们将被解析。

更新资料

dbenham答案的更新给了我一些想法。首先-在两种情况下,我们可能需要多行注释-在无法使用GOTO的上下文中以及在它之外。括号内的情况下,我们可以用另一种支架是否有防止代码是executed.Though代码thede仍然会被解析,将被检测的一些语法错误(条件FORIF,非正常关闭括号,错误的参数扩展..)。所以,如果可能的话,最好使用GOTO。

虽然无法创建用作标签的宏/变量-但可以将宏用于括号的注释。仍然可以使用两个技巧使GOTO注释更加对称和令人愉悦(至少对我而言)。为此,我将使用两个技巧-1)您可以在标签前放置一个符号,goto仍然可以找到它(我不知道为什么会这样,我的想法是要搜索驱动器)。2)您可以: 在变量名的末尾添加一个,并且不会触发替换/替代功能(即使在启用的扩展名下)。Wich与用于括号注释的宏结合可以使两种情况看起来几乎相同。

所以这是示例(按照我最喜欢的顺序):

矩形括号

@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
)

1
您可以使用rem.||(rem^ (代替。意图更加清晰。看到我更新的答案。
dbenham

@dbenham-是的,与rem较短。
npocmaka

1
哦,方括号和大括号形式很性感。如果我只是为自己编写代码,则可以使用它。但是我想普通用户会看到并说出WTF。
dbenham

@dbenham-也许您是对的。我也可以包含%rem:%+ %:rem%形式,使其更明显,尽管它会失去它的魅力。或者仅斜线使其更接近C风格...
npocmaka

1
@npocmaka太棒了!我在弄清楚自己做了什么的同时,学到了很多批处理脚本的复杂性。在我所知道的所有批处理注释方法中(批处理),该方法似乎是最可靠,最聪明的。结合技巧和风格的+1
Jared Gotte

10

另一种选择是将不需要的行封装在永远不会为真的IF块中

if 1==0 (
...
)

当然,if块中的任何内容都不会执行,但是会被解析。因此,您不能在其中包含任何无效的语法。同样,)除非被转义或引用,否则评论不能包含。由于这些原因,公认的GOTO解决方案更加可靠。(GOTO解决方案也可能更快)

更新2017-09-19

这是pdub的GOTO解决方案的一个外观增强。我定义了一个简单的环境变量“宏”,使GOTO注释语法可以更好地自我记录。尽管通常建议:labels在批处理脚本中是唯一的,但确实可以在这样的批处理脚本中嵌入多个这样的注释。

@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解决方案的这些变体之一。使用REM而不是BREAK可以使意图更加清晰。

rem.||(
   remarks
   go here
)

rem^ ||(
   The space after the caret
   is critical
)

1

只是想提一下,如果:comment标签多次出现,pdub的GOTO解决方案并不完全正确。我以这个问题为例修改代码。

@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

跳过第一个块中TD_NEXT处的命令ECHO HERE AT


0

@jeb

使用此命令后,似乎无法访问stderr

不,请尝试以下操作:

@echo off 2>Nul 3>Nul 4>Nul

   ben ali  
   mubarak 2>&1
   gadeffi
   ..next ?

   echo hello Tunisia

  pause

但是为什么行得通呢?

抱歉,我用法语回答这个问题:

(按重定向参数3>使用率不断变化的EST专用车2>使用各种变压器保持性的EST 3>选择合适的方法erreur pour tot notre environement de script..par la suite si on veux recuperer le flux'stderr'il faut faire a unre redirection du handle 2> au handle 1> qui n'est autre que la console ..)


1
我看不懂法语,但您似乎无法解决初始重定向结束后为什么流2(stderr)仍被禁用的问题。在dostips.com/forum/viewtopic.php?p=14612#p14612的 2个连续帖子中,我有一个可行的理论和测试用例。
dbenham

(3>重定向是特殊的,因为它会持续存在,我们将使用它来捕获错误流2>会将其转变为3之前的持久流>这将使我们能够为任何一个管理错误环境脚本..然后,如果要恢复流“ stderr”,我们必须进行另一个句柄重定向2>来处理a>控制台以外的其他内容..)
user96403

-1

试试这个:

   @echo off 2>Nul 3>Nul 4>Nul

   ben ali
   mubarak
   gadeffi
   ..next ?

   echo hello Tunisia

  pause

+1,但为什么有效?在使用此选项之后,似乎无法访问stderr
jeb 2011年

1
-1,之所以有效,是因为echo 2> Nul将标准错误流重定向到NUL,并将其掩埋(3> Nul,4> Nul没有实际原因将重定向辅助流)。这不会注释掉这些行,而只是防止显示错误消息。因此,任何可以解释为命令行的内容仍将运行。
pdubs 2011年

3
pdubs注释部分正确,因为命令仍在执行(并且由于无效而失败)。但是有效的命令将执行而不会失败。因此,这不是注释掉代码行的好方法。关于为何“永久”禁用流2(stderr)的解释不正确。
dbenham

3
我有一个关于Windows批处理中重定向如何工作的理论,它解释了为何在此答案中stderr被“永久”禁用。理论和测试在dostips.com/forum/viewtopic.php?p=14612#p14612
dbenham 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.