Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to write some status info that replaces the last line when I do something.

In following example bat file, I want the text Step 2 to overwrite Step 1 on the same line in the command output.

echo off

echo Step 1
REM Do some stuff...

echo Step 2
REM do some other stuff...
share|improve this question
add comment

4 Answers

up vote 3 down vote accepted

This script will do exactly what you asked:

@echo off

setlocal enableextensions enabledelayedexpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "ASCII_13=%%a"

set /p "=Step 1" <NUL
REM Do some stuff...

set /p "=!ASCII_13!Step 2" <NUL
REM do some other stuff...

I found this answer by looking at the code in a batch script character manipulation library written by Dave Benham called CharLib. Source code here: https://sites.google.com/site/dbenhamfiles/home/CharLib_bat.txt

This library is able to create all characters in the range 1..255.

For more info see the thread entitled "Is it possible to convert a character to its ASCII value?"

share|improve this answer
add comment

To answer the question:

@echo off
CALL :EVALUATE "chr(8)"
SET backspace=%result%
<nul set /p =Step 1
:: DO SOME STUFF....
<nul set /p =%backspace%
<nul set /p =2
:: DO SOME OTHER STUFF....
<nul set /p =%backspace%%backspace%%backspace%%backspace%%backspace%%backspace%
<nul set /p =End   
GOTO:EOF



:EVALUATE           -- evaluate with VBS and return to result variable
::                  -- %~1: VBS string to evaluate
:: extra info: http://groups.google.com/group/alt.msdos.batch.nt/browse_thread/thread/9092aad97cd0f917

@IF [%1]==[] ECHO Input argument missing & GOTO :EOF 

@ECHO wsh.echo "result="^&eval("%~1") > %temp%\evaluate_tmp_67354.vbs 
@FOR /f "delims=" %%a IN ('cscript //nologo %temp%\evaluate_tmp_67354.vbs') do @SET "%%a" 
@DEL %temp%\evaluate_tmp_67354.vbs
::ECHO %result%
@GOTO:EOF

Output:

End

Basically, what the script does, is writes Step 1, then goes back one place, overwrites 1, and at the end goes completely back and overwrites Step 2 with End.

This going back I do with the special ASCII character 8 which is backspace. Because I don’t know how to write it in cmd, I use the :EVALUATE function which runs the VBS Chr() function, and puts the backspace-character into the variable result. If someone knows a better way, please advise.

share|improve this answer
1  
In PowerShell, you can also store $host.ui.RawUI.CursorPosition into a variable and restore it later to have the cursor jump back at where you were and overwrite your output. Only an option for PowerShell, but may be a bit cleaner than your VBS stuff :-) –  mihi Sep 25 '12 at 19:08
add comment

You can't. Usually you can achieve this kind of thing by including a carriage-return character (0x0D) in the file which will put the cursor back to the first column in the same line. But in this case it doesn't work; the CR is just silently eaten.

Furthermore getting the CR in there is kinda tricky and at least here involved a text editor. I'd suggest you write a little utility program that will do this for you, it actually isn't very hard. The following little C program might suffice (if you don't need Unicode):

#include <stdio.h>

int main(int argc, char* argv[]) {
  if (argc < 2) return 1;
  printf("\r%s", argv[1]);
}

It does nothing more than printing a CR character and then the text you specify as its first argument. Usage as follows:

@echo off
<nul set /P X=Step 1
pause>nul 2>nul
over.exe "Step 2"

The last line is the call to that program. The second line is the normal batch idiom for printing text without a trailing line break (which is important in this case because otherwise you couldn't overwrite the line). You could just as well use the program above as well in that place, though.

A lightly hacky way, but the only one where you can be sure where you end up, would be to use cls prior to your step output. Will flicker but that way you always write to the upper-left. And clobber everything that was visible in the console (which is why I wouldn't recommend it); most users don't like that too much.

share|improve this answer
    
OK, I had a suspicion it was not possible to do with clean command line. If I want to make a utility do do this, I might as well put the entire thing in a utility. What I really wanted was just a visible countdown that wait 5 seconds, counting down each second till finished. –  awe Dec 14 '09 at 7:59
4  
awe: If you are on Vista or later, then timeout 5 will work. –  Јοеу Dec 14 '09 at 8:02
    
Great! thank you! timeout 5 works! –  awe Dec 14 '09 at 8:30
3  
I should have posted my real issue the first time... –  awe Dec 14 '09 at 8:31
add comment

You'd need a screen-cursor library like curses or ncurses, but I'm not overly familiar with their use. Both libraries were developed for Unix systems, but you can find them for Windows (in the Cygwin environment, or GnuWin32).

I don't know of any easy way to access them in a DOS-style batch file. You might be better off programming in a compiled language. Take a look at the Ncurses HOWTO to get a better idea of whether it will be useful.

share|improve this answer
    
curses are pretty much for terminals and terminal emulators only. They don't really map to Windows's native console API. –  Јοеу Dec 14 '09 at 9:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.