I found this program web.archive.org: http://baiyunmanor.com/blog/work/get-current-date-time-in-dos-batch-file/
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: This uses Windows Scripting Host to set variables
:: to the current date/time/day/day_number
:: for Win9x/ME/NT/W2K/XP etc
:: Thanks go to Todd Vargo for his scripting
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#echo off
set TmpFile=”%temp%.\tmp.vbs”
echo> %TmpFile% n=Now
echo>>%TmpFile% With WScript
echo>>%TmpFile% .Echo “set year=” + CStr(Year(n))
echo>>%TmpFile% .Echo “set yr=” + Right(Year(n),2)
...
cscript //nologo “%temp%.\tmp.vbs” > “%temp%.\tmp.bat”
call “%temp%.\tmp.bat”
...
echo date F [ddmmyy] [%day%%month%%yr%]
:: datetime.bat
But I don't know what does the line
:: datetime.bat
at the end mean?
:: is a label (inaccurately also known as comment label) can be, in practice, considered a comment just as REM is, because it is an "un-goto-able" label.
There are some differences between REM and ::, though. The main ones are:
With ECHO ON a REM line is shown but not a line commented with ::
A :: can execute a line end caret (that is, a ^ at the end of a line starting with :: makes the next line also a comment):
:: This is a comment^
echo but watch out because this line is a comment too
Labels and :: have a special logic and can cause problems in parentheses blocks - take care when using them inside ( ). Example:
for %%D in (hi) do (
echo Before...
:: My comment
:: Some other comment
echo After...
)
Outputs:
Before ...
The system cannot find the drive specified.
After...
A line that start in double colon represent an invalid label that is ignored by the command processor, so it may be used to insert a comment. For reasons that can't be traced, many people use :: to insert comments in Batch files, but you must be aware that there are several pitfalls in its use that are described in the link given in Koterpillar's answer. It seems that the first use of :: instead of REM command was with the purpose to speed up the execution of Batch files in slow machines (ie: floppy disks), but that reason is not a valid justification for the use of double colon since many years ago.
Any line that contain an invalid label will be ignored by the command processor and you may use practically any special character to generate an invalid label. For example:
#echo off
:~ This is a comment
:` This is a comment
:! This is a comment
:# This is a comment
:# This is a comment
:$ This is a comment
:% This is a comment
:^ This is a comment
:& This is a comment
:* This is a comment
:( This is a comment
:) This is a comment
:_ This is a comment
:- This is a comment
:+ This is a comment
:= This is a comment
:{ This is a comment
:} This is a comment
:[ This is a comment
:] This is a comment
:| This is a comment
:\ This is a comment
:: This is a comment
:; This is a comment
:" This is a comment
:' This is a comment
:< This is a comment
:> This is a comment
:, This is a comment
:. This is a comment
:? This is a comment
:/ This is a comment
echo OK
In other words: if you want to insert a comment and you want not to use REM command (although I can't think of any reason to do so), you have 32 possible character combinations to do so. Why you should use precisely this one: ::? Just because some old programs written 35 years ago did it?
A line starting with a colon is a label which you can jump to with goto:
goto end
:end
A line starting with a double colon is a label, except you can't, even accidentally, jump to it:
goto :end REM this doesn't work
::end
Thus, double colon is used to comment lines out.
Source: http://www.robvanderwoude.com/comments.php
As mentioned by acdcjunior Labels and :: have a special logic and can cause problems in parenthesis blocks
Here are couple of samples
Sample 1
IF 1==1 (
::
)
Output of sample 1
) was unexpected at this time.
Sample 2
IF 1==1 (
::
::
)
Output of sample 2
The system cannot find the drive specified.
The colon (:) is a label marker and can be used for got instructions.
Some people use : as a comment too so a double colon is simply a stylistic REM statement
If you use the traditional REM command to comment out a line in a DOS batch script then any output redirection in the comment is still done. For example, consider this script:
echo 1 > a.txt
rem echo 2 > b.txt
echo 3 > c.txt
This script will truncate b.txt even though the line appears to be "commented out".
Using an invalid label prefix like the double colon will disable any redirection.
Related
Is there a solution to: The %1 parameter is incorrect when a file or folder that has an & (ampersand) or a ^ (caret), and no space in its full name is dropped onto a batch file?
After running into this problem myself, I am posting a solution for review and to give back for all I have learned from ss64.com and stackoverflow.com – Thank you!
From my testing, the enclosed batch file works for all but the command line character limitation.
Solution for & and ^:
Regarding the %1 parameter:
Drops with spaces in them are workable because a space auto invokes surrounding double quotation marks which escape all special characters within that quoted string.
Ampersands and carets require the same process that spaces receive but that process is not invoked for them.
A workaround solution is to use and modify %cmdcmdline% so that it provides surrounding double quotation marks for each dropped file and folder. This also results in a consistent formatting of the parameters which simplifies processing.
The workaround is shown in the accompanying batch file.
Of equal importance to the workaround, is the control and predictability of double quotation marks:
While the workaround is straightforward, the implementation and effects of double quotation marks needs to be understood in order to prevent them from causing errors throughout the batch file.
One pair of surrounding double quotation marks escapes all special characters within that quoted string.
Two pairs of surrounding double quotation marks are functionally the same as no double quotation marks, which results in nothing being escaped and any special characters remain active (batch files do not have a left or a right quotation mark -- open quote is closed by the very next unassigned quotation mark).
When possible, avoid double quotes embedded in parameters and variables.
Negate embedded double quotes with "%~1" or strip them by using set "var=%var:"=%"
Unless necessary, use set "var=value" rather than set var="value"
In the enclosed batch file the protective double quotation marks are:
Internal in !params! during preprocessing,
Consumed in a For Command,
Kept external for "%_Dropped%" during processing
This work is based on and gratefully acknowledged to jeb's strategy and code at:
https://ss64.org/viewtopic.php?id=1168
"dragdrop file named with ampersand problem" - 13 Jan 2011 15:07
Also, thank you allal for your well asked questions years before I had them.
P.S. I wrote here what I needed to know before this started.
Side note: (there may be other uses for this) echoing a single digit to a text file failed for me until () were added, try:
echo 9>> con & (echo 9)>> con
:: Code ... Stable_Params.bat
#prompt $g
#if "%~1"=="" echo This batch file requires that at least one file or folder is dropped onto it - & echo Press any key to exit . . .& pause > nul & exit
#set drop__count=0
#set exist_count=0
#echo --- %%cmdcmdline%% is ... (with no double quote control, special characters can cause errors in this command)
#echo %cmdcmdline%
goto Preproc_Params
=== Instructions:
Drop files and folders with names that contain ampersands or carets, and with and without spaces in them, onto this batch file.
Also, for media root drops: drop one and multiple drive letters onto this batch file.
=== Passes the cartoon swear word folder name test: (This test's failures prompted this solution)
To see a failure: in the Test_Loop remove the #rem from either of the rem'd out lines, and drop onto this batch file a folder with this name... !##$+~%(-^&`,;)
=== To ensure there are double quotes surrounding each drop to a batch file, and then processing them:
(1) Enable Delayed Expansion to allow the %~d1 parameter within !! and for containing special characters.
(2) set params equal to the parameters by replacing the start of !cmdcmdline! through its first "<space> with "
(3) strip all double quotes within !params! while setting one pair of surrounding double quotes into !params!
(4) for multiple media root drops (drive letters): insert double quotes into !params! by replacing \<space> with \"<space>"
(5) for multiple file/folder drops: insert double quotes into !params! by replacing <space><drive:> with "<space>"<drive:>
(6) Disable Delayed Expansion so drops with an ! (exclamation mark) in their full name are workable.
(7) For Command to consume the quotes; parse the parameters, assign them to a variable, and process them in a called loop.
(8) During processing surround "%_Dropped%" with one pair of double quotes to disable the activation of special characters.
:Preproc_Params
#setlocal EnableDelayedExpansion
#set "params=!cmdcmdline:*" ="!"
#set params="!params:"=!"
#set "params=!params:\ =\" "!"
#set "params=!params: %~d1=" "%~d1!"
#setlocal DisableDelayedExpansion
#echo.
#echo --- double quote adjusted %%params%% with the start of %%cmdcmdline%% through its first "<space> replaced with "
#echo %params%
:: Split the parameters on spaces but respect and consume the quotes
#for %%G in (%params%) do (set "_Dropped=%%~G" & set /a "drop__count+=1" & call :Test_Loop)
goto TestLoop_Done
:Test_Loop
#if exist "%_Dropped%" (set /a "exist_count+=1") & (echo "%%_Dropped%%" is "%_Dropped%")
#if not exist "%_Dropped%" (echo "%_Dropped%" does not exist, or it is drive letter with no media)
:: When not rem'd out, the following line with certain drops will cause a failure and possibly a window exit
#rem #(echo %%_Dropped%% is %_Dropped%)
:: A second pair of surrounding double quotes acts the same as no quotes -- open quote is closed by the next quotation mark
#rem #(echo ""%%_Dropped%%"" is ""%_Dropped%"")
#exit /b
:TestLoop_Done
#echo.
#(echo %%drop__count%% is__ %drop__count%)
#(echo %%exist_count%% is__ %exist_count%)
#echo.
#echo Press any key to exit . . . & pause > nul
:: Code end ---
i was toying around with cmd a bit and wanted to write a little application which involves a simple feature to read a counter from a txt file, then work with it and at the end raise the counter by one.
set /p x=<file.txt
...
set /a y=x+1
echo %y%>file.txt
Problem is it always returns "ECHO ist eingeschaltet (ON)." which translates to ECHO is turned on (ON) for some reason. Could somebody please explain where it comes from and how to fix it? I dont need anything fancy. I just want it to work and know where my mistake is.
At first, I want to show you how your echo command line should look like:
> "file.txt" echo(%y%
Here is your original line of code again:
echo %y%>file.txt
The reason for the unexpected output ECHO is on./ECHO is off. is because the echo command does not receive anything to echo (type echo /? and read the help text to learn what on/off means). Supposing y carries the value 2, the line expands to:
echo 2>file.txt
The number 2 here is not taken to be echoed here, it is consumed by the redirection instead; according to the article Redirection, 2> constitutes a redirection operator, telling to redirect the stream with the handle 2 (STDERR) to the given file. Such a handle can reach from 0 to 9.
There are some options to overcome that problem:
inserting a SPACE in between the echoed text and the redirection operator:
echo %y% >file.txt
the disadvantage is that the SPACE becomes part of the echoed text;
placing parentheses around the echo command:
(echo %y%)>file.txt
placing the redirection part at the beginning of the command line:
>file.txt echo %y%
I prefer the last option as this is the most general and secure solution. In addition, there is still room for improvement:
quote the file path/name to avoid trouble in case it contains white-spaces or other special characters;
use the odd syntax echo( to be able to output everything, even an empty string or literal strings like on, off and /?;
> "file.txt" echo(%y%
Hint:
To see what is actually going on, do not run a batch file by double-clicking on its icon; open a command prompt window and type its (quoted) path, so the window will remain open, showing any command echoes and error messages. In addition, for debugging a batch file, do not put #echo off on top (or comment it out by preceding rem, or use #echo on) in order to see command echoes.
Echo on means that everything that is executed in the batch is also shown in the console. So you see the command and on the following line the result.
You can turn this off with the echo off command or by preceding a # sign before the command you want to hide.
so
::turns of the echo for the remainder of the batch or untill put back on
::the command itself is not shwn because off the #
#echo off
set /p x=<file.txt
...
::the following won't be shown regardless the setting of echo
#set /a y = x+1
echo %y% > file.txt
EDIT after first comment
because your command echo %y%>file.txt doesn't work, you need a space before the > symbol, now you get the result of echo which gives you the current setting of echo
here a working sample, I put everything in one variable for sake of simplicity.
echo off
set /p x =< file.txt
set /a x += 1
echo %x% > file.txt
I want to split a string in two parts, without using any for loop.
For example, I have the string in a variable:
str=45:abc
I want to get 45 in a variable and abc in another variable. Is it possible in batch file?
pattern is like somenumber:somestring
You could split the str with different ways.
The for loop, you don't want use it.
The trailing part is easy with the * (match anything until ...)
set "var2=%str:*:=%"
The leading part can be done with a nasty trick
set "var1=%str::="^&REM #%
The caret is needed to escape the ampersand,
so effectivly the colon will be replaced by "&REM #
So in your case you got the line after replacing
set "var1=4567"&REM #abcde
And this is splitted into two commands
set "var1=4567"
REM #abcde`
And the complete code is here:
set "str=4567:abcde"
echo %str%
set "var1=%str::="^&REM #%
set "var2=%str:*:=%"
echo var1=%var1% var2=%var2%
Edit 2: More stable leading part
Thanks Dave for the idea to use a linefeed.
The REM technic isn't very stable against content with quotes and special characters.
But with a linefeed trick there exists a more stable version which also works when the split argument is longer than a single character.
#echo off
setlocal enableDelayedExpansion
set ^"str=456789#$#abc"
for /F "delims=" %%a in (^"!str:#$#^=^
!^") do (
set "lead=%%a"
goto :break
)
:break
echo !lead!
Solution 3: Adpated dbenhams answer
Dbenham uses in his solution a linefeed with a pipe.
This seems a bit over complicated.
As the solution uses the fact, that the parser removes the rest of the line after an unescaped linefeed (when this is found before or in the special character phase).
At first the colon character is replaced to a linefeed with delayed expansion replacement.
That is allowed and the linefeed is now part of the variable.
Then the line set lead=%lead% strips the trailing part.
It's better not to use the extended syntax here, as set "lead=%lead%" would break if a quote is part of the string.
setlocal enableDelayedExpansion
set "str=45:abc"
set ^"lead=!str::=^
!"
set lead=%lead%
echo "!lead!"
You can try this . If its fixed that numbers to left of the colon will be always 2 & to the right will be 3. Then following code should work assuming your str has the value.
set "str=45:abc"
echo %str%
set var1=%str:~0,2%
set var2=%str:~3,3%
echo %var1% %var2%
Keep me posted. :)
It seems pointless to avoid using a FOR loop, but it does make the problem interesting.
As jeb has pointed out, getting the trailing part is easy using !str:*:=!.
The tricky bit is the leading part. Here is an alternative to jeb's solution.
You can insert a linefeed into a variable in place of the : using the following syntax
setlocal enableDelayedExpansion
set "str=45:abc"
echo !str::=^
!
--OUTPUT--
45
abc
The empty line above the last ! is critical.
I'm not sure why, but when the output of the above is piped to a command, only the first line is preserved. So the output can be piped to a FINDSTR that matches any line, and that result directed to a file that can then be read into a variable using SET /P.
The 2nd line must be eliminated prior to using SET /P because SET /P does not recognize <LF> as a line terminator - it only recognizes <CR><LF>.
Here is a complete solution:
#echo off
setlocal enableDelayedExpansion
set "str=45:abc"
echo(!str::=^
!|findstr "^" >test.tmp
<test.tmp set /p "var1="
del test.tmp
set "var2=!str:*:=!"
echo var1=!var1! var2=!var2!
Update
I believe I've mostly figured out why the 2nd line is stripped from the output :)
It has to do with how pipes are handled by Windows cmd.exe with each side being processed by a new CMD.EXE thread. See Why does delayed expansion fail when inside a piped block of code? for a related question with a great answer from jeb.
Just looking at the left side of the piped command, I believe it is parsed (in memory) into a statement that looks like
C:\Windows\system32\cmd.exe /S /D /c" echo {delayedExpansionExpression}"
I use {delayedExpansionExpression} to represent the multi-line search and replace expansion that has not yet occurred.
Next, I think the variable expression is actually expanded and the line is broken in two by the search and replace:
C:\Windows\system32\cmd.exe /S /D /c" echo 43
abc"
Only then is the command executed, and by normal cmd.exe rules, the command ends at the linefeed. The quoted command string is missing the end quote, but the parser doesn't care about that.
The part I am still puzzled by is what happens to the abc"? I would have thought that an attempt would be made to execute it, resulting in an error message like 'abc"' is not recognized as an internal or external command, operable program or batch file. But instead it appears to simply get lost in the ether.
note - jeb's 3rd comment explains why :)
Safe version without FOR
My original solution will not work with a string like this & that:cats & dogs. Here is a variation without FOR that should work with nearly any string, except for string length limits and trailing control chars will be stripped from leading part.
#echo off
setlocal enableDelayedExpansion
set "str=this & that:cats & dogs"
set ^"str2=!str::=^
!^"
cmd /v:on /c echo ^^!str2^^!|findstr /v "$" >test.tmp
<test.tmp set /p "var1="
del test.tmp
set "var2=!str:*:=!"
echo var1=!var1! var2=!var2!
I delay the expansion until the new CMD thread, and I use a quirk of FINDSTR regex that $ only matches lines that end with <cr>. The first line doesn't have it and the second does. The /v option inverts the result.
Yes, I know this is a very old topic, but I just discovered it and I can't resist the temptation of post my solution:
#echo off
setlocal
set "str=45:abc"
set "var1=%str::=" & set "var2=%"
echo var1="%var1%" var2="%var2%"
You may read full details of this method here.
In the Light of people posting all sorts of methots for splitting variables here i might as well post my own method, allowing for not only one but several splits out of a variable, indicated by the same symbol, which is not possible with the REM-Method (which i used for some time, thanks #jeb).
With the method below, the string defined in the second line is split into three parts:
setlocal EnableDelayedExpansion
set fulline=one/two/three or/more
set fulline=%fulline%//
REM above line prevents unexpected results when input string has less than two /
set line2=%fulline:*/=%
set line3=%line2:*/=%
set line1=!fulline:/%line2%=!
set line2=!line2:/%line3%=!
setlocal DisableDelayedExpansion
echo."%line1%"
echo."%line2%"
echo."%line3%"
OUTPUT:
"one"
"two"
"three or/more//"
i recommend using the last so-created partition of the string as a "bin" for the remaining "safety" split-characters.
Here's a solution without nasty tricks for leading piece
REM accepts userID#host
setlocal enableDelayedExpansion
set "str=%1"
set "host=%str:*#=%"
for /F "tokens=1 delims=#" %%F IN ("%str%") do set "user=%%F"
echo user#host = %user%#%host%
endlocal
I have a batch file that runs several python scripts that do table modifications.
I want to have users comment out the 1-2 python scripts that they don't want to run, rather than removing them from the batch file (so the next user knows these scripts exist as options!)
I also want to add comments to bring to their attention specifically the variables they need to update in the Batch file before they run it. I see that I can use REM. But it looks like that's more for updating the user with progress after they've run it.
Is there a syntax for more appropriately adding a comment?
Use :: or REM
:: commenttttttttttt
REM commenttttttttttt
BUT (as people noted):
if they are not in the beginning of line, then add & character:
your commands here & :: commenttttttttttt
Inside nested parts (IF/ELSE, FOR loops, etc...) :: should be followed with normal line, otherwise it gives error (use REM there).
:: may also fail within setlocal ENABLEDELAYEDEXPANSION
The rem command is indeed for comments. It doesn't inherently update anyone after running the script. Some script authors might use it that way instead of echo, though, because by default the batch interpreter will print out each command before it's processed. Since rem commands don't do anything, it's safe to print them without side effects. To avoid printing a command, prefix it with #, or, to apply that setting throughout the program, run #echo off. (It's echo off to avoid printing further commands; the # is to avoid printing that command prior to the echo setting taking effect.)
So, in your batch file, you might use this:
#echo off
REM To skip the following Python commands, put "REM" before them:
python foo.py
python bar.py
No, plain old batch files use REM as a comment. ECHO is the command that prints something on the screen.
To "comment out" sections of the file you could use GOTO. An example of all these commands/techniques:
REM it starts here the section below can be safely erased once the file is customised
ECHO Hey you need to edit this file before running it! Check the instructions inside
ECHO Now press ctrl-c to interrupt execution or enter to continue
PAUSE
REM erase the section above once you have customised the file
python executed1.py
ECHO Skipping some stuff now
GOTO End
python skipped1.py
python skipped2.py
:END
python executed2.py
What can I say? batch files are a relic of times long gone, they're clunky and ugly.
You can read more on this website.
EDIT: modified the example a bit to have it contain the elements you are apparently looking for.
The :: instead of REM was preferably used in the days that computers weren't very fast.
REM'ed line are read and then ingnored. ::'ed line are ignored all the way. This could speed up your code in "the old days". Further more after a REM you need a space, after :: you don't.
And as said in the first comment: you can add info to any line you feel the need to
SET DATETIME=%DTS:~0,8%-%DTS:~8,6% ::Makes YYYYMMDD-HHMMSS
As for the skipping of parts.
Putting REM in front of every line can be rather time consuming.
As mentioned using GOTO to skip parts is an easy way to skip large pieces of code. Be sure to set a :LABEL at the point you want the code to continue.
SOME CODE
GOTO LABEL ::REM OUT THIS LINE TO EXECUTE THE CODE BETWEEN THIS GOTO AND :LABEL
SOME CODE TO SKIP
.
LAST LINE OF CODE TO SKIP
:LABEL
CODE TO EXECUTE
Multi line comments
If there are large number of lines you want to comment out then it will be better if you can make multi line comments rather than commenting out every line.
See this post by Rob van der Woude on comment blocks:
The batch language doesn't have comment blocks, though there are ways
to accomplish the effect.
GOTO EndComment1
This line is comment.
And so is this line.
And this one...
:EndComment1
You can use GOTO Label and :Label for making block comments.
Or, If the comment block appears at the end of the batch file, you can
write EXIT at end of code and then any number of comments for your
understanding.
#ECHO OFF
REM Do something
•
•
REM End of code; use GOTO:EOF instead of EXIT for Windows NT and later
EXIT
Start of comment block at end of batch file
This line is comment.
And so is this line.
And this one...
Putting comments on the same line with commands: use & :: comment
color C & :: set red font color
echo IMPORTANT INFORMATION
color & :: reset the color to default
Explanation:
& separates two commands, so in this case color C is the first command and :: set red font color is the second one.
Important:
This statement with comment looks intuitively correct:
goto error1 :: handling the error
but it is not a valid use of the comment. It works only because goto ignores all arguments past the first one. The proof is easy, this goto will not fail either:
goto error1 handling the error
But similar attempt
color 17 :: grey on blue
fails executing the command due to 4 arguments unknown to the color command: ::, grey, on, blue.
It will only work as:
color 17 & :: grey on blue
So the ampersand is inevitable.
You can comment something out using :: or REM:
your commands here
:: commenttttttttttt
or
your commands here
REM commenttttttttttt
To do it on the same line as a command, you must add an ampersand:
your commands here & :: commenttttttttttt
or
your commands here & REM commenttttttttttt
Note:
Using :: in nested logic (IF-ELSE, FOR loops, etc...) will cause an error. In those cases, use REM instead.
You can add comments to the end of a batch file with this syntax:
#echo off
:: Start of code
...
:: End of code
(I am a comment
So I am!
This can be only at the end of batch files
Just make sure you never use a closing parentheses.
Attributions: Leo Guttirez Ramirez on https://www.robvanderwoude.com/comments.php
Commenting a line
For commenting line use REM or :: though :: might fail inside brackets
within delayed expansion lines starting with !<delimiter> will be ignored so this can be used for comments:
#echo off
setlocal enableDelayedExpansion
echo delayed expansion activated
!;delayed expansion commented line
echo end of the demonstration
Comment at the end of line
For comments at the end of line you can again use rem and :: combined with &:
echo --- &:: comment (should not be the last line in the script)
echo --- &rem comment
Commenting at the end of file
As noting will be parsed after the exit command you can use it to put comments at the end of the file:
#echo off
echo commands
exit /b
-------------------
commnts at the end
of the file
------------------
Inline comments
Expansion of not existing variables is replaced with nothing ,and as setting a variable with = rather hard you can use this for inline comments:
#echo off
echo long command %= this is a comment =% with an inline comment
Multiline comments
For multiline comments GOTO (for outside brackets) and REM with conditional execution (for inside brackets) can be used. More details here:
#echo off
echo starting script
goto :end_comments
comented line
one more commented line
:end_comments
echo continue with the script
(
echo demonstration off
rem/||(
lines with
comments
)
echo multiline comment inside
echo brackets
)
And the same technique beautified with macros:
#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
)
I prefer to use:
REM for comments
&REM for inline comments
Example:
#echo off
set parameter1=%1%
REM test if the parameter 1 was received
if defined parameter1 echo The parameter 1 is %parameter1% &REM Display the parameter
This is an old topic and I'd like to add my understanding here to expand the knowledge of this interesting topic.
The key difference between REM and :: is:
REM is a command itself, while :: is NOT.
We can treat :: as a token that as soon as CMD parser encounters the first non-blank space in a line is this :: token, it will just skip the whole line and read next line. That's why REM should be followed by at least a blank space to be able to function as a comment for the line, while :: does not need any blank space behind it.
That REM is a command itself can be best understood from the following FOR syntax
The basic FOR syntax is as follows
FOR %v in (set) DO <Command> [command param]
here <Command> can be any valid command
So we can write the following valid command line as rem is a command
FOR %i in (1,2,3) DO rem echo %i
However, we CANNOT write the following line as :: is not a command
FOR %i in (1,2,3) DO :: echo %i
You can use :: or rem for comments.
When commenting, use :: as it's 3 times faster. An example is shown here
Only if comments are in if, use rem, as the colons could make errors, because they are a label.
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?
You can use a goto to skip over code.
goto comment
...skip this...
:comment
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:
Select the block of lines
hit Ctrl-Q
Repeat steps to uncomment
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
)
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
)
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.
#jeb
And after using this, the stderr seems to be inaccessible
No, try this:
#echo off 2>Nul 3>Nul 4>Nul
ben ali
mubarak 2>&1
gadeffi
..next ?
echo hello Tunisia
pause
But why it works?
sorry, i answer the question in frensh:
( 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 environement 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 console.. )
try this:
#echo off 2>Nul 3>Nul 4>Nul
ben ali
mubarak
gadeffi
..next ?
echo hello Tunisia
pause