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

Posted

技术标签:

【中文标题】在 DOS 批处理文件中注释多行【英文标题】:Commenting multiple lines in DOS batch file 【发布时间】:2012-01-21 13:17:12 【问题描述】:

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

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

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

您可以使用goto 跳过代码。

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

【讨论】:

我觉得有趣的是命令行中没有真正的注释定义,我只是不能接受REM 行作为注释行,这使得输出模糊【参考方案2】:

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

    选择行块 按Ctrl-Q

重复步骤以取消注释

【讨论】:

不错的提示。让它更干净。 哇,不知道notepad++有这么好的功能!实际上真的很想念它,因为我习惯了 Eclipse 中的 `Ctrl+7'。投票达到 42 ;) 取消注释怎么样。在那里有任何快捷方式可以取消注释整个块。 @BhaskarSingh 从 Notepad++ 7.5.6 开始,您只需突出显示已注释的文本即可;执行“Ctrl + Q”,它会取消注释 您也可以在块的开头用SHIFT-ALT和向下箭头以列模式选择行并键入“REM”,然后选择相同的方式并删除删除。【参考方案3】:
break||(
 code that cannot contain non paired closing bracket
)

虽然goto 解决方案是一个不错的选择,但它不会工作within brackets(包括 FOR 和 IF 命令)。但这会。尽管您应该小心 FORIF 命令的右括号和无效语法,因为它们将被解析。

更新

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^ (。意图更清晰一些。请参阅我的更新答案。 哦,方括号和大括号的形式很性感。如果我只是为自己编写代码,我可能会使用它。但我想普通用户会看到并说 WTF。 @npocmaka 这太棒了!我刚刚学习了一堆复杂的批处理脚本,同时弄清楚了你做了什么。从我所知道的所有块注释方法(对于批处理)中,这个方法似乎是最健壮和最聪明的。 +1 结合 hack 和风格 rem.||(@dbenham 建议是唯一对我有用的解决方案。但老实说,我只是好奇,只是使用内置于 Notepad++ 中的格式化工具。但有时让我来到这里的是对条件块中的多行使用 :: 而不是 REM,例如 FOR LOOP 会破坏脚本。 @jacktrader - 我建议你使用 rem/||( 。如果在同一目录中有一个名为rem 的文件,使用rem 会产生错误。【参考方案4】:

另一种选择是将不需要的行包含在一个永远不会为真的 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.【参考方案5】:

只想提一下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 被跳过。

【讨论】:

【参考方案6】:

@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控制台..)

【讨论】:

我看不懂法语,但您似乎没有解决为什么在初始重定向结束后流 2 (stderr) 继续被禁用的原因。我在dostips.com/forum/viewtopic.php?p=14612#p14612 的两个连续帖子中有一个可行的理论和测试用例。 (Redirection by 3> 是特殊的,因为它会持续存在,我们将使用它来捕获错误流 2> 它将把它变成一个持续流到 ade of 3> 这将允许我们我们的任何环境脚本都有一个管理错误..那么如果你想恢复流'stderr',我们必须进行另一个句柄重定向2>来处理a>,它就是控制台..)【参考方案7】:

试试这个:

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

   ben ali
   mubarak
   gadeffi
   ..next ?

   echo hello Tunisia

  pause

【讨论】:

+1,但为什么它有效?使用这个之后,stderr 似乎无法访问 -1,这“有效”,因为 echo 2>Nul 将标准错误流重定向到 NUL,将其掩埋(3>Nul、4>Nul 无缘无故地重定向辅助流)。这不会注释掉这些行,它只是防止显示错误消息。所以任何可以解释为命令行的东西仍然会运行。 pdubs 注释部分正确,因为命令仍在执行(并且由于无效而失败)。但是有效的命令会执行而不会失败。所以这不是注释掉代码行的好解决方案。关于为什么流 2(stderr)被“永久”禁用的解释是不正确的。 我有一个关于重定向如何在 Windows 批处理中工作的理论,它解释了为什么 stderr 在这个答案中被“永久”禁用。理论和测试在dostips.com/forum/viewtopic.php?p=14612#p14612的连续2个帖子中@

以上是关于在 DOS 批处理文件中注释多行的主要内容,如果未能解决你的问题,请参考以下文章

在BAT文件里用啥符号来注释?如果我要让它DOS中显示,而不让它运行呢?有没有办法!~

bat中如何添加注释

dos 批处理命令 删除指定后缀条件的文件

在BAT文件里用啥符号来注释?

dos 批处理 如果不换行追加内容到文件。

dos批处理