Generate Any Control Character
ASCII has 33 control characters. Many of them are defunct or are used for purposes for which they were not originally intended. Most of them are unprintable and some can cause problems if not filtered out of input. All the same, a handful of these characters have proven to be indispensible when it comes to performing certain tasks in Batch.
In this post, I’ll show you commonly-used techniques for generating specific control characters, as well as two lesser-known methods for storing almost any control character in a variable. But finding uses for them is an entirely different matter. One which will be covered in an upcoming post.
The Null Character
In Batch, there’s no way of storing the Null Character (ASCII 0, NUL) in a variable. But you can create a one-byte file consisting of a single null character by entering the command below:
fsutil file createnew nul.tmp 1
nul.tmp will be created in the current directory. Also, in some versions of Windows, the
fsutil command can only be executed by the administrator. In which case, you’ll have to execute the
fsutil command above from a Command Prompt running with administrator privileges.
Backspace and Escape
prompt command supports “dollar escapes” (eg,
prompt $a places an ampersand (&) in the prompt,
prompt $g outputs a greater-than (>), and so on). Type
prompt /? for the full list.
Two of these dollar escapes happen to be control characters: Backspace (ASCII 8, BS); and Escape (ASCII 27, ESC).
The code to capture BS in a variable is explained in this DosTips topic, but here it is in a nutshell:
for /f %%a in ('""prompt $h&for %%b in (1) do rem""') do set bs=%%a echo(no %bs%visible %bs%spaces
prompt $h with
prompt $e if you want Escape.
Line Feed (ASCII 10, LF) is the easiest control character to store in a variable. Simply do this:
(set lf=^ )
and you’re done! Just remember to leave the second line blank.
Batch expert Dave Benham recently discovered that the
cls command emits a Form Feed (ASCII 12, FF) character. Storing it in a variable is simply a matter of:
for /f %%f in ('cls') do set ff=%%f
Carriage Return (ASCII 13, CR) can be stored in a variable by using the following code snippet:
for /f %%c in ('copy /z ""%~dpf0"" nul') do set cr=%%c
But how anyone ever figured that out, I’ll never know! 😈 Anyways, please note that due to the way
cmd parses input, CR can only be used when delayed expansion is enabled.
The conventional way of storing Control Z (ASCII 26, SUB) in a variable is to create an empty file using
copy /a which appends Ctrl-Z to the end of the file. And then pass the file to a
for /f loop so its contents can be
set to a variable. All of which looks something like:
copy nul sub.tmp /a >nul for /f %%s in (sub.tmp) do set sub=%%s del sub.tmp
I say “conventional” because there are newer techniques (outlined below) for achieving the same thing that do not require a temporary file.
Most text editors allow you to insert any control character from the Numeric Keypad. For instance, to enter a null character:
- Make sure Num Lock is on.
- Hold down the Alt key.
256on the Numeric Keypad.
You can also use this procedure to enter characters such as Bell (ASCII 7, BEL). Remember to type three digits for every character. For instance, Bell would be <Alt+007>.
Control characters can be typed in manually from the Command Prompt by holding down the Control key and pressing the letter corresponding to their ASCII value.
For instance, pressing <Ctrl+G> would output Bell because Bell is ASCII 7 and G is the seventh letter of the alphabet (see this ASCII table for the full list of keystrokes). Try it for yourself by typing this command:
You should hear a short beep when you press <Enter>.
This works from the command line, but how do you save it to a file? No problem! Just redirect command line output to a file called
>bel.cmd echo(set ""bel=<Ctrl+G>""
Now you can edit
bel.cmd and output the
%bel% variable whenever you want to make the computer beep.
Btw, typing <Ctrl+@> from the Command Prompt is supposed to output a null character, but I could never get it to work.
A hybrid script can be used to store any control character in a variable except Nul, LF and CR.
The example below (modified from an answer on Stack Overflow) shows how to generate a Horizontal Tab (ASCII 9, HT). The
"delims=" is necessary when capturing a tab because
for /f uses tab and space as default delimiters.
@if (@X)==(@Y) @goto dummy @end /* @echo off & setlocal enableextensions for /f ""delims="" %%t in ('cscript //e:jscript //nologo ""%~dpf0""') do set tab=%%t echo(words%tab%separated%tab%by%tab%tabs endlocal & exit /b 0 */ WScript.Echo(""\x09"");
Please note that the argument to
WScript.Echo() must be given in hexadecimal. For example, the hexadecimal for Escape (ASCII 27, ESC) would be
Another method of generating and storing any control character in a variable (apart from NUL, LF, and CR) is to exploit a feature of the
forfiles command. The code to obtain Control Z (ASCII 26, SUB), for instance, should go a little something like this:
for /f %%s in ( 'forfiles /p ""."" /m ""%~nx0"" /c ""cmd /c echo(0x1a""' ) do set sub=%%s
The problem with
forfiles is that it doesn’t ship with all versions of Windows. However, if it’s not on your system, you might be lucky and find a link to a download floating around on the web somewhere. 😉
And this concludes the round-up of all the ways I know of generating control characters and how to store them in variables. If I’ve left anything out, or if you’d like to give me your feedback, please leave a comment.