6

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

n611x007
  • 8,952
  • 8
  • 59
  • 102
  • 1
    look here: http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line – Stephan Jan 26 '14 at 18:52
  • @Stephan thanks, using http://stackoverflow.com/a/13941131/611007 it seems possible albeit with the [gnuwin32's coreutils](http://gnuwin32.sourceforge.net/packages/coreutils.htm) package: `echo blah | tr -d "\n"` :) not too optimal but at least it works! – n611x007 Jan 26 '14 at 18:58
  • 1
    [How to overwrite the same line in command output from batch file](https://superuser.com/q/82929/241386) – phuclv May 23 '19 at 05:38
  • Possible duplicate of [How do I clear ONLY ONE LINE of cmd?](https://stackoverflow.com/questions/42450295/how-do-i-clear-only-one-line-of-cmd) – phuclv May 23 '19 at 05:38

4 Answers4

11

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.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • ahhh - I was so close. My solution did not work, because I had the !cr! at the beginning of the string. Thank you for the explanation. +1 – Stephan Jan 27 '14 at 06:27
  • 1
    docs for the CR hack: it relies on a specific behaviour of the `/Z` [switch of copy](http://technet.microsoft.com/en-us/library/bb490886.aspx). about `%~dfp0", see [Using batch file parameters](http://technet.microsoft.com/en-us/library/bb490890.aspx) – n611x007 Apr 29 '14 at 17:56
  • What if at the time I print message I don't know if I will need to continue in print without CR or not? Any chance to do some workaround about printing `!CR!` separately, or with some non-standard white space, such as `chr(160) + CR` to allowed to use CR only when really needed? – Ωmega Feb 24 '20 at 20:19
1

Somewhere along the line, "echo\" works to print a [cr] line. Great for ending an output from some other command that doesn't put [cr] at the end. I've used this for sending CR to files as in IPconfig | find "Reply" >>myip.txt and then echo\ >>myip.txt

Ed Kurata
  • 11
  • 1
1

Building on dbenham's post, I have the following routines that work in Win7 and mostly editable in Notepad; however, I used Scite to generate the backspace, ALT+008, character. It differs slightly by first clearing the row, and placing the cursor at the end of the text. Here are the routines:

:RECHO
<nul set/p"=backspace!CR!tabtabtabtabtabtabtabtabtabtab"
<nul set/p"=backspace!CR!%*"
GOTO :EOF
:NECHO
<nul set/p"=backspace!CR!tabtabtabtabtabtabtabtabtabtab"
ECHO backspace!CR!%*
GOTO :EOF

dbenham's example modified:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

FOR /F %%a IN ('copy /Z "%~dpf0" nul') DO SET "CR=%%a"
SET "BS="

ECHO Testing CR. This line a regular echo ...
CALL :RECHO Part 1 - press a key
pause >nul
CALL :RECHO Part 2 - press a key
pause >nul
CALL :NECHO Part 3 - Finished
ECHO Testing CR. This line a regular echo ...
GOTO END

:RECHO
<nul set/p"=!BS!!CR!                                                "
<nul set/p"=!BS!!CR!%*"
GOTO :EOF

:NECHO
<nul set/p"=!BS!!CR!                                                "
ECHO !BS!!CR!%*
GOTO :EOF

:END
ENDLOCAL
EXIT /B

When copying the above script, make sure the backspace character is preserved.

    SET "BS=backspace"
bvj
  • 3,294
  • 31
  • 30
-1

Here's how I catch & echo 0x0A in cmd:

(
set n=^

)

Then to test:

echo Ila!n!you
echo Ila!n!!n!you
set /p="la!n!"<nul > newline

You may see the written file via hex viewer eg fc or comp

00000000: 00 6C
00000001: 00 61
00000002: 00 0A

Tested in Win 10 CMD

Zimba
  • 2,854
  • 18
  • 26
  • 1
    to overwrite the last line, `LF` isn't helpful at all. You'd need `CR`. The question wasn't about echoing a linefeed, but (over)writing to the same line again and again. – Stephan Oct 22 '20 at 17:34
  • @Stephan: The question in the section "question" is "to somehow echo a carriage-return (or other non-printable) character". Read the question before you start voting on other's answers, esp. if you can't come up with an answer yourself! – Zimba Oct 25 '20 at 03:12
  • A carriage-return (`CR`) sets the cursor at the start of the current line. A Linefeed (`LF`) sets the cursor to the next line. Different things (yes, I read the question...). And there are several good answers, so why should I clutter this page with a similar answer? Btw you shouldn't assume by default that a downvote is necessarily from a commenter (it is in this case, but it's mostly not). – Stephan Oct 25 '20 at 08:07
  • @Stephan: `CR` is different from `LF`. Do you know any other way to `echo` "non-printable"s from CMD? Feel free to share. (without any externals, of course ideally without JS, HTA, VBS, or downloads) – Zimba Oct 25 '20 at 10:00
  • 1
    [Dbenham](https://stackoverflow.com/users/1012053/dbenham) has listed a great collection of methods [here](https://stackoverflow.com/a/47826309/2152082). – Stephan Oct 25 '20 at 10:11