Search code examples
windowsbatch-filecmdcarriage-returnnon-printing-characters

Is it possible to echo some non-printable characters in batch/cmd?


motivation

I have a 3rd party, somehow long .bat file written for some specific function and would take considerable effort to re-write (which effort is also hindered by my problem). In for loops the most basic way to debug it would seem echoing some information to the screen. I used to do this with \r (0x0D) character in other languages that on some terminals/console re-writes the same line (to avoid overflooding, since in my case the last line would contain the error). I already save the value to a variable. However, since iteration might take quite long, I'd still be happy to write some output to the screen that won't overflood.

what I've tried

  • I know I can echo a single newline in cmd with echo. - however I need only the carriage return
  • I've tried these but they did't work: echo \r, echo ^r, echo \x0d, echo ^x0d, echo #0d, echo ^#0d, echo #x0d, echo ^x0d
  • I've tried to duck the net for similar stuff without much help

question

Is it possible to somehow echo a carriage-return (or other non-printable) character in a windows/dos/nt/cmd batch file?

ps. I use the XP or the 7 cmd processor


Solution

  • You need two hacks - one to define a carriage return character, and another to echo a line of text without issuing the newline character.

    1) Define carriage return.

    :: Define CR to contain a carriage return (0x0D)
    for /f %%A in ('copy /Z "%~dpf0" nul') do set "CR=%%A"
    

    Once defined, the value can only be accessed via delayed expansion - as in !CR!, not %CR%.

    2) Print text to the screen without issuing a newline

    <nul set /p "=Your message here"
    

    This will fail if the string starts with a =.

    Also, leading quotes and/or white space may be stripped, depending on the Windows version

    Putting it all together

    @echo off
    setlocal enableDelayedExpansion
    
    :: Define CR to contain a carriage return (0x0D)
    for /f %%A in ('copy /Z "%~dpf0" nul') do set "CR=%%A"
    
    <nul set/p"=Part 1 - press a key!CR!"
    pause >nul
    <nul set/p"=Part 2 - press a key!CR!"
    pause >nul
    <nul set/p"=Part 3 - Finished   !CR!"
    

    Note that I put the !CR! at the end of each message in preparation for the next. You cannot put the !CR! at the beginning because leading white space will be stripped.