<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

DOS: ECHO text to previous line - by Paul Tomasi

Published on
36,854 Points
25,754 Views
16 Endorsements
Last Modified:
Awarded
Community Pick
One of my most closely kept secrets is revealed in this discussion

How to output text on the same line


This question was recently posted in EE by Simon336697

Consider the problem:

ECHO Hello
ECHO World

Open in new window


This would output the following to the screen:

    Hello
    World

However, what if we wanted the words Hello and World to appear on the same line as in:

    Hello World

This could be done as follows:

ECHO Hello World

Open in new window


But this discussion is not about that. This discussion explores the possibility of outputting text to the previous line.


Now consider the following:

    output text to screen
    process other commands
    output more text to the same line

Impossible? Read on....


Firstly, let's use Simon336697's question as an example:

    1)  output "Searching...." to screen
    2)  PING
    3)  output (append) result to the same line

Before we continue, let's refine these instructions:

 1   )  output "Searching for %Computer%.... " to screen
 2   )  PING %Computer% >NUL 2>&1
 3.1)  if ping fails...
 3.2)     output "FAIL" to previous line
 3.3)  otherwise...
 3,4)     output "SUCCESS" to previous line
 3.5)  end-if

[step=""][Ed Note]: The 2>&1 portion simply redirects STDERR to STDOUT.  
Thus, the sequence >NULL 2>&1 totally silences the PING command.[/step]
And, this is what the code would look like in a DOS batch file:

ECHO Searching for %Computer%.... 

PING %Computer% >NUL 2>&1

IF ERRORLEVEL 1 (
   ECHO FAIL
) ELSE (
   ECHO SUCCESS
)

Open in new window


However, in the case of a successful PING, the output would still be as follows:

    Searching....
    SUCCESS

To enable ECHOing to the previous line then, the following syntax is used to suppress the cursor:

SET /P Var=text<NUL

Open in new window

where Var is any variablename and text is the text output to the screen.


Normally, SET /P Var=text takes it's input from STDIN, the standard input device. This is usually the keyboard.

Rather than SET /P= accepting input from STDIN, we can force it to accept input from another device, in this case, the NUL device. This is done by redirecting output from NUL to SET /P= however, because NUL does not produce any output, SET /P= waits until it receives input, in this case, from the ECHO command.

So, with only a minor change to our program, this would now look something like the following:

SET /P var=Searching for %Computer%....<NUL

PING %Computer% >NUL 2>&1

IF ERRORLEVEL 1 (
   ECHO FAIL
) ELSE (
   ECHO SUCCESS
)

Open in new window


And this time, in the case of a successful PING, the output is as follows:

    Searching for PC1....SUCCESS

where the variable %Computer% is set to PC1.

Finally, notice how PING's output is redirected to NUL. This is to ensure any output it produces is not sent to STDOUT, the standard output device, as SET /P= would capture this instead of capturing output from the ECHO command.
.
16
Comment
Author:t0t0
  • 5
  • 4
  • 4
  • +7
22 Comments
LVL 1

Expert Comment

by:Simon336697
t0t0, that is so helpful thanks so much for this :>)
0
LVL 44

Expert Comment

by:Steve Knight
Cool!  Never knew that one, thanks Paul..... noted.

You can extend that too then using set /p to print the "second" line and therefore keeping adding as you like... I can't seem to get PING to return an errorlevel for failed pings for me for some reason but you could keep some kind of progress counter while a process runs:

@echo off
mode con: cols=40 lines=4
color 4f
title Please Wait
echo                    0                100
SET /P var=Progress counter : <NUL

set count=0
:loop
  PING -n 2 127.0.0.1 >NUL 2>&1
  call :printline .
  set /a count=count+1
  if %count%==20 goto finish
goto loop

:printline
 REM Print text passed to sub without a carriage return.
 REM Sets line variable in case %1 intereferes with redirect
 set line=%1
 set /p var=%line%<NUL
exit /b

:finish
cls
color 0f
title Finished
mode con: cols=80 lines=25
echo Thankyou, all done now.
pause
exit /b
0
LVL 74

Expert Comment

by:Qlemo
Steve,
that is how Paul used it, or at least at the first occurence in a question I have seen - as a progress indicator. It is a good idea, and I have adopted it since then on several occasions ;-) I too have never seen it before Paul introduced (invented?) it.
About the ping issue: It seems as ping returns an errorlevel starting with XP.

Simon,
Did you vote "Yes"? If not, please do so, it is important for article authors to get that voting feedback!
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

LVL 16

Author Comment

by:t0t0
Thank you qlemo for your thoughtful comments....
0
LVL 21

Expert Comment

by:AmazingTech
Great tip t0t0!

I would just add @ECHO OFF to the first line of your code for all the newbies out there.
0
LVL 16

Author Comment

by:t0t0
Thank you AmazingTech.

As you know, I've always had a high regard for you and as ever, your suggestion is very welcome.... and of course, very appropriate where newbies are concerned.
0
LVL 16

Author Comment

by:t0t0
Thank you Dan...
0
LVL 16

Expert Comment

by:Giovanni Heward
Very nice.  I wasn't aware of this.  Here is a modified example which incorporates multiple instances.

<b>Please Wait.........</b> with a second delay between each period.

Good for progress indicator, etc.  :)

I used to return to the previous line using ANSI escape sequences.  Really cool to see this in use without requiring ANSI driver.

@echo off
set /p a=Please wait<nul
set b=1
:loop
set /p a=.<nul
choice /t 1 /c y /d y>nul
set /a b=%b%+1
if %b%==10 goto :eof
goto :loop

Open in new window

0
LVL 16

Expert Comment

by:Giovanni Heward
Here is a install progress example using ascii characters ... kinda fun to play around with.
install.progress.bat.txt
0
LVL 17

Expert Comment

by:Kent Dyer
I think this can be done even simpler..  Even back to the original post: "Being on one line."

HTH,

Kent

ECHO Hello
ECHO World


ECHO Hello & ECHO World

pause

Open in new window

0
LVL 44

Expert Comment

by:Steve Knight
Kent - I think paul's point here was this is a way of printing to the screen without a carriage return in the OUTPUT not in the batch file.

Steve
0
LVL 16

Author Comment

by:t0t0
kdyer

You have not grasped the essence of this article. Look at the following code VERY carefully and try to understand what it is I am achieving with the 'SET /P' and '<NUL' command.


    SET /P var=Searching for %Computer%....<NUL

    PING %Computer% >NUL 2>&1

    IF ERRORLEVEL 1 (
       ECHO FAIL
    ) ELSE (
       ECHO SUCCESS
    )


The only other way (well, one such possible way) you could do this is:


    PING %Computer% >NUL 2>&1

    IF ERRORLEVEL 1 (
       ECHO Searching for %Computer%....FAIL
    ) ELSE (
       ECHO Searching for %Computer%....SUCCESS
    )


But that would not be correct because quite clearly, by the time we get to the IF statement, we have ALREADY 'searched' using PING. so the message "Searching for %Computer%...." ("FAIL" or "SUCCESS")  is out of context with the code.

If none of this makes sense to you then try this simple program to see what effect it produces:


    FOR /L %%a IN (0,1,9) DO (
        SET /P .=%%a <NUL
    )


As opposed to this:


    FOR /L %%a IN (0,1,9) DO (
        ECHO %%a
    )
0
LVL 16

Expert Comment

by:Ben Personick (Previously QCubed)
Very Nice find t0t0! =)
0
LVL 16

Expert Comment

by:Giovanni Heward
I found out by using this method we can strip carriage returns when outputting to files... when creating a flat csv file for example.

Example:
 
@echo off
for /f "delims=?" %%f in ('dir/s/ad/b/on 2^>^>error.log') do (
	set /p dir=%%f;<nul>>list.csv
)

Open in new window

0
LVL 44

Expert Comment

by:Steve Knight
Nice idea.  You can do it without having to do the >> append for each line too by redirecting the whole for command into a file once:

@echo off
(for /f "delims=?" %%f in ('dir/s/ad/b/on 2^>^>error.log') do (
        set /p dir=%%f;<nul
))>list.csv

Steve
0
LVL 16

Expert Comment

by:Giovanni Heward
@Steve, wow... learned something new!  I didn't know you could do that... :)
0
LVL 11

Expert Comment

by:Paul Tomasi
Hey, hiya x66_x72_x65_x65

Nice to receive feedback occasionally...

SET /P with <NUL suppresses the carriage-return/Linefeed characters. As you've discovered, and as one would expect, this also works when redirecting output.

By the way, I don't think you need to redirect STDERR to error.log as DIR /A:D will always be true even if there are no subdirectories (not absolutely sure for the root directory though so please don't shoot me down over this).

Also check out the following command:

   (FOR /R . %%f IN (.) DO SET /P .=%%~Ff<NUL)>list.csv

Hope that's useful for ya.

0
LVL 16

Expert Comment

by:Giovanni Heward
@paultomasi:Thanks for the feedback and example code.  An STDERR condition exists whenever the maximum directory/file length is encountered.  The purpose of the STDERR redirect is to create a clean .csv without the possibility of any embedded error messages.
0
LVL 26

Expert Comment

by:Steven Carnahan
I just stumbled across this article.  There was a question just the other day that I was following.  I will certainly make use of this in some of my batch files.   :)

Thank you t0t0 and all contributors.
0
LVL 11

Expert Comment

by:Paul Tomasi
No probs...

BTW, since writing this article, I discovered you don't need an Lvalue so:

    set /p .=<nul

can also be written as:

    set /p =<nul

(I use a full-stop, or period, as an example but it could just as well be any allowable identifier)
0
LVL 44

Expert Comment

by:Steve Knight
I have used this method too in the past to make it more obvious (ish):

SET PRINT=^<NUL set /p =

Then in the area needed you can do:

%PRINT% What I want to print

or

SET echox=^<NUL set /p =
%echox% mytext

etc.

Steve
0
LVL 74

Expert Comment

by:Qlemo
Just to throw in another variant:
doskey echox=^<nul set /p=$*

Open in new window

and you can use echox everywhere in the current shell. Looks better than %echox%, IMO.
0

Featured Post

Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

Join & Write a Comment

Microsoft Office 365 Backup and Restore Solution by SysTools to export Office 365 mailbox to PST / EML file format on Windows OS. On Mac, tool backup O365 to PST / MBOX / MSG / EML / EMLX file formats. Not only this, restore option helps to import s…
I previously published an Experts Exchange video Micro Tutorial that describes how to scan documents to a PDF file using an excellent, free product called Foxit Reader: How to scan to a PDF file with free software (https://www.experts-exchange.co…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month