Specifically for cmd.exe on Windows Operating Systems.
It is a common occurrence in the Programming Forum to see questions related to creating text files with a batch script, be it to create a secondary script or a particular format of text file. This “How-To” will attempt to outline all of the information needed to create files successfully.
Cmd/Bat scripting by default creates ANSI encoded text files unless cmd.exe was started with the “/U” switch, in which case in will create Unicode formatted text files(Without a byte-order-mark). It is only the output file that differs, the procedure to create the file is the same.
Creating text files in batch is easy, there are two main operators:
“>” – Output the command to file, overwrite it if it already exists, otherwise create it.
“>>” – Output the command to file, append to the end of the file it if it already exist, otherwise create it.
rem output the dir command to file, overwrite the file if it already exists. dir > "somefile.txt" rem Equivilant to above > "somefile.txt" dir rem output the dir command to file, append to the file if it already exists. dir >> "somefile.txt" rem Equivilant to above >> "somefile.txt" dir
The syntax is very easy, but of course there are a few rules:
(I) The file name must come after the redirection symbol(s).
(II) The file name must be double quoted if it contains spaces or ampersands.
(III) Relative or full paths can be used; if only a file name is specified then the file is created in the current directory.
(IV) The act of redirection can be before or after the command.
Almost any command that outputs text, including other scripts and error streams, can be redirected to file. Programs that write directly to the console window can’t be redirected, though few programs actually do this.
Redirection of Grouped Commands
“Grouped commands” or “code blocks” can be redirected to file in a single step. This can save typing and generally make the script look much cleaner.
This means that if statements and for loops can be output in a single step, rather that redirecting each individual command. Again the redirection can come immediately before or after “code block”.
rem "if" if 1==1 ( dir echo 1==1! ) >> "somefile.txt" rem "if/else" if 1==1 ( dir echo 1==1! ) >> "somefile.txt" else ( echo what ) >> "somefile.txt" rem "for" for %%a in (1 2 3) do ( echo %%a ) >> "somefile.txt" rem standalone codeblock ( Echo All of this echo only gets echo redirected once! ) >> "somefile.txt"
It is important to remember to take into account variable expansion issues when inside a “code block”.
Redirecting the Error Stream
Thus far we have only been redirecting the standard output of commands, but some commands will output errors in a different way. It is still possible to redirect this error stream to a file, in fact it’s possible to output only the error stream or even combine it with the standard output stream so both go to the same file.
In batch script streams are noted by the numbers 0 – 9, of which there are three usable streams(0 – 2). As far as output goes only stream “1” (standard output) and stream “2” (error) need to be considered.
When addressing a particular stream the number that denotes the stream must be immediately before the redirection operator, if omitted(as in the above examples) the standard stream is assumed.
rem only errors into "somefile.txt" find "" : 2>> "somefile.txt" rem errors into "errors.txt" rem and standard output to "somefile.txt" dir /arashd 2>> "errors.txt" >> "somefile.txt" rem errors and standard output to somefile.txt dir /arashd >> "somefile.txt" 2>&1
As you can see above you simply insert a “2” in front of the redirection operator to output errors and that errors can go to one file with the standard output to another.
You may have noticed the strange looking “2>&1”, this redirects the error stream into the standard output stream. It always follows the same syntax “x>&y” where “x” is the stream to be mixed with stream “y”. This stream redirection must come after any file redirection, the changes are still reflected in the output.
Using the Echo Command
The “echo” command can be a very useful tool when creating files. It allows a whole line to be specified and can be partially or completely variable content. However there are a few key considerations when using echo.
If you redirect after “echo” and leave a space between the last character and the redirection symbol you may be left with a trailing space in the output. It is possible to omit the space but it can lead to further problems(see “Accidental Stream Redirection”).
rem I don't recommend either of these methods echo This will have a trailing space > "somefile.txt" echo This won't, but could have other issues> "somefile.txt"
If you want the output text to contain leading spaces or tabs then a colon (:) needs to be added after “echo”. A side effect of this is that the usual space between “echo” and the output text is also output. The exact number of leading spaces/tabs required should be after the colon, do not add the usual space to delimit the command and text.
>> "somefile.txt" echo: - This line has leading spaces.
This form of echo also works without leading spaces, so it can be used generally; mixing forms is not required.
Using “echo” with a colon also makes it possible to output empty lines. The following outputs an empty line into “somefile.txt”:
>> "somefile.txt" echo:
Accidental stream redirection
The catch with redirecting after echo and not leaving a space is that if the last character is a number and second last is a space cmd.exe thinks you want a particular stream redirected. This is also an issue with “standard” percentage sign(%) enclosed variables, as they are treated as plain text.
The easiest and most reliable method to avoid both trailing spaces and accidental redirection is to redirect before echo.
>> "somefile.txt" echo The best of both worlds!
Of course this can still result in trailing spaces, but only if the text you output has them.
The final catch that echo has for us is dealing with characters that have special meaning to the command processor. The main problem is that most of the escaping is conditional.
To start out I will quickly go over the variable types. There are four variable types in batch script, two are treated as plain text, and thus not already escaped, the other two are already escaped.
%1 - Parameter, not escaped. %var% - Standard Environment Variable, not escaped %%a - For Variable, escaped. !var! - Delayed Environment Variable, escaped
When used with echo the escaped variables can hold any characters(except possibly the exclamation mark(!)) without any issue, those that aren’t escaped must already contain the necessary escape sequence(s).
The percentage sign(%) always needs to be doubled.
If already inside a variable it is already escaped.
The exclamation mark(!) only needs to be escaped if Delayed Expansion is enabled. If it is then it must be escaped by two carets(^).
SetLocal EnableDelayedExpansion echo ^^!
It is also worth noting that exclamation marks will either disappear or expand as variables inside of Parameters, Standard Environment Variables and For Variables, unless the variable has the right number of carets already in it(four or more depending on the circumstance).
The closing Parentheses character “)” needs to be escaped if the echo is inside a “code block”.
( echo ^) )
The Greater-Than(>), Less-Than (<), Pipe (|), Ampersand(&) and Caret(^) symbols all need to be escaped by a caret(^) unless they are contained within “double quotes”.
echo ^> ^< ^| ^& ^^
Well that’s all for this “How-To”, I hope you have enjoyed!