Commenting multiple lines in DOS batch file

121,071

Solution 1

You can use a goto to skip over code.

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

Solution 2

If you want to add REM at the beginning of each line instead of using GOTO, you can use Notepad++ to do this easily following these steps:

  1. Select the block of lines
  2. hit Ctrl-Q

Repeat steps to uncomment

Solution 3

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

While the goto solution is a good option it will not work within brackets (including FOR and IF commands).But this will. Though you should be careful about closing brackets and invalid syntax for FOR and IF commands because they will be parsed.

Update

The update in the dbenham's answer gave me some ideas. First - there are two different cases where we can need multi line comments - in a bracket's context where GOTO cannot be used and outside it. Inside brackets context we can use another brackets if there's a condition which prevents the code to be executed.Though the code thede will still be parsed and some syntax errors will be detected (FOR,IF ,improperly closed brackets, wrong parameter expansion ..).So if it is possible it's better to use GOTO.

Though it is not possible to create a macro/variable used as a label - but is possible to use macros for bracket's comments.Still two tricks can be used make the GOTO comments more symetrical and more pleasing (at least for me). For this I'll use two tricks - 1) you can put a single symbol in front of a label and goto will still able to find it (I have no idea why is this.My guues it is searching for a drive). 2) you can put a single : at the end of a variable name and a replacement/subtring feature will be not triggered (even under enabled extensions). Wich combined with the macros for brackets comments can make the both cases to look almost the same.

So here are the examples (in the order I like them most):

With rectangular brackets:

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

With curly brackets:

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

With parentheses:

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

Mixture between powershell and C styles (< cannot be used because the redirection is with higher prio.* cannot be used because of the %*) :

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

To emphase that's a comment (thought it is not so short):

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

Solution 4

Another option is to enclose the unwanted lines in an IF block that can never be true

if 1==0 (
...
)

Of course nothing within the if block will be executed, but it will be parsed. So you can't have any invalid syntax within. Also, the comment cannot contain ) unless it is escaped or quoted. For those reasons the accepted GOTO solution is more reliable. (The GOTO solution may also be faster)

Update 2017-09-19

Here is a cosmetic enhancement to pdub's GOTO solution. I define a simple environment variable "macro" that makes the GOTO comment syntax a bit better self documenting. Although it is generally recommended that :labels are unique within a batch script, it really is OK to embed multiple comments like this within the same batch script.

@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

Or you could use one of these variants of npocmaka's solution. The use of REM instead of BREAK makes the intent a bit clearer.

rem.||(
   remarks
   go here
)

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

Solution 5

Just want to mention that pdub's GOTO solution is not fully correct in case :comment label appear in multiple times. I modify the code from this question as the example.

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

The output will be

IN THE FIRST IF...
HERE AT TD_NEXT IN THE SECOND BLOCK

The command ECHO HERE AT TD_NEXT IN THE FIRST BLOCK is skipped.

Share:
121,071

Related videos on Youtube

user219628
Author by

user219628

Updated on September 06, 2021

Comments

  • user219628
    user219628 over 2 years

    I have written huge MS DOS Batch file. To test this batch file I need to execute some lines only and want to hide/comment out remaining.

    I have some existing comment lines starting with :: hence I cannot use :: anymore as it will scramble all comments.

    How can I solve this problem?

  • jeb
    jeb over 12 years
    +1, But why it works? And after using this, the stderr seems to be inaccessible
  • pdubs
    pdubs over 12 years
    -1, This "works" because echo 2>Nul is redirecting the standard error stream to NUL, burying it (the 3>Nul, 4>Nul are redirecting auxiliary streams for no real reason). This does not comment out the lines, it merely prevents error messages from showing. So anything that can be interpreted as command lines will still run.
  • dbenham
    dbenham about 12 years
    pdubs comment is partially correct in that the commands are still executing (and failing because not valid). But valid commands would execute without failure. So this is not a good solution for commenting out lines of code. The explanation as to why stream 2 (stderr) is "permanently" disabled is not correct.
  • dbenham
    dbenham about 12 years
    I have a theory as to how redirection works in Windows batch, and it explains why stderr becomes "permanently" disabled in this answer. The theory and tests are in 2 consecutive posts at dostips.com/forum/viewtopic.php?p=14612#p14612
  • dbenham
    dbenham about 12 years
    I can't read french, but it doesn't look like you address why stream 2 (stderr) continues to be disabled after the initial redirection is over. I have a workable theory and test cases in 2 consecutive posts at dostips.com/forum/viewtopic.php?p=14612#p14612.
  • user96403
    user96403 about 12 years
    (Redirection by 3> is special because it persists, we will use it to capture the flow of errors 2> is it will turn it into a persistent flow to ade of 3> this will allow us to have a management error for any of our environment script .. then if you want to recover the flow 'stderr' we must make another handle redirection 2> to handle a> which is none other than the console ..)
  • ango
    ango about 11 years
    Nice tip. makes it much cleaner.
  • Danny Lo
    Danny Lo over 8 years
    Wow, didn't know notepad++ has such a nice feature! Actually really missed it because I'm used to `Ctrl+7' in Eclipse. Voted up to 42 ;)
  • Bhaskar Singh
    Bhaskar Singh over 6 years
    What about uncomment. In there any shortcut to uncomment the entire block.
  • dbenham
    dbenham over 6 years
    You could use rem.||( or rem^ ( instead. The intent is a bit clearer. See my updated answer.
  • npocmaka
    npocmaka over 6 years
    @dbenham - yes with rem it's shorter.
  • dbenham
    dbenham over 6 years
    Ooh, the square and curly bracket forms are sexy. If I were writing code only for myself I might use it. But I imagine the average user would see that and say WTF.
  • npocmaka
    npocmaka over 6 years
    @dbenham - may be you are right.I can include %rem:% + %:rem% form too to make it more obvious though it will loose it's charm.Or only slash to be closer to the C-style...
  • mkb
    mkb over 6 years
    I think what's funny is there is no real comment definition in command line, I just can't accept REM lines as comment lines, it makes the output obscure
  • Jared Gotte
    Jared Gotte over 6 years
    @npocmaka This is awesome! I just learned a bunch of batch scripting intricacies while figuring out what you did. From all the block comment methods I'm aware of (for batch), this one seems to be the most robust and clever. +1 for combining hack and style
  • CreativiTimothy
    CreativiTimothy almost 6 years
    @BhaskarSingh As of Notepad++ 7.5.6, you can simply just highlight the already commented text; do "Ctrl + Q", and it will uncomment it
  • Timo
    Timo almost 5 years
    If your brain is often weak like mine to remember Ctrl-Q, click in Notepad++ : Edit -> Comment/Uncomment.
  • RockDoctor
    RockDoctor almost 5 years
    You can also SHIFT-ALT at the start of the block and down arrow to select the rows in column mode and type "REM ", then select the same way and delete to remove.
  • aschipfl
    aschipfl over 3 years
    …or rem/||(…) which would be safe opposed to rem.
  • jacktrader
    jacktrader almost 3 years
    rem.||( suggested by @dbenham was the only solution that worked for me. But honestly, I was just curious and just use formatting tools built into Notepad++.. but what brought me here is sometimes using :: instead of REM for multiple lines in a condition block, like a FOR LOOP breaks the script.
  • npocmaka
    npocmaka almost 3 years
    @jacktrader - I would suggest you to use rem/||( . If you have a file called rem in the same directory using rem will produce an error.