Solution: to write multiple times on the same line

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Solution: to write multiple times on the same line

#1 Post by jeb » 03 Apr 2010 14:08

Hello,

the set /p command has some interessting features.

The normal usage is to display a text and wait for an answer, finished by <Enter>.

Code: Select all

set /p user=Enter your name?


But you can use it also to display only a text like

Code: Select all

set /p someVar=Display this text < nul


or the same with an other notation

Code: Select all

<nul set /p "=Display this text"


Ok. But that seems to be the same like the echo command.
But not excactly, the set /p variant does not append the CR/LF at the end of the line.

So there are different results for

Code: Select all

echo Line1
echo Line2

result:
Line1
Line2


Code: Select all

<nul set /p ".=Line1"
<nul set /p ".=Line2"

result:
Line1Line2


This is enough for a simple progress bar.

But with a further trick you can use it to solve an other type of problem.
Count a number on a line, or generally replace text on a line, without clearing the whole screen.

You only need to print a CR (0x0d) character, to move the cursor again at the first position of the line.
Ok, you need a single CR character. But this can be done with a file.

Code: Select all

@echo off
setlocal
setlocal enabledelayedexpansion

:: Assign a single CR to a variable, use a textfile with 2 bytes of 0x0d, 0x0d
for /f "tokens=1" %%x in ('type cr.txt') do set CR=%%x

::Simple sample, count from 1 to 2000, print it on the same line
for /L %%c in ( 1,1,2000) do (
   <nul set /p ".=!CR!Count %%c"
)


This works fine ... on XP, but not under Vista anymore.

It's because Vista have implemented a "feature" for the set /p, stripping all white space (space, tab, and CR) behind the equal sign.
But only the front will stripped, not the end.

Code: Select all

<nul set /p ".= Hello "
<nul set /p ".=two"

result XP:
<space>Hello two
 
result Vista
Hello two


But there is a work around, place the CR at the end or after a non space character

Code: Select all

<nul set /p ".=Count %%c!CR!"

or
<nul set /p ".=_!CR!Count %%c"


Attention:
After the equal sign it's not allowed to place direct an other equal sign (after stripping the whate spaces)
This will not work, and results in an error.

Code: Select all

set /p ".=   ="


Finally:

Code: Select all

@echo off
setlocal
setlocal enabledelayedexpansion

:: Assign a single CR to a variable, use a textfile with 2 bytes of 0x0d, 0x0d
for /f "tokens=1" %%x in ('type cr.txt') do set CR=%%x

::Simple sample, count from 1 to 2000, print it on the same line
for /L %%c in ( 1,1,2000) do (
   <nul set /p ".=Count %%c!CR!"
)


hope it helps
Jan Erik
Last edited by jeb on 08 Apr 2010 04:05, edited 1 time in total.

DosItHelp
Expert
Posts: 239
Joined: 18 Feb 2006 19:54

Re: How to write multiple times on the same line

#2 Post by DosItHelp » 06 Apr 2010 21:39

Very interesting Jan - thanks for sharing this!

This line executed at the command line creates the text file with the 'CR CR' in it in the current directory.

Code: Select all

(echo.N cr.txt&echo.e 100 0d 0d&echo.r cx&echo.02&echo.w 100&echo.q)|debug>NUL

---saster---
Posts: 5
Joined: 07 Apr 2010 06:49

Re: Solution: to write multiple times on the same line

#3 Post by ---saster--- » 07 Apr 2010 11:53

this is very useful in effects, like progress bar

a matrix effect

@echo off

setlocal enabledelayedexpansion

mode con cols=40 lines=20
color 0A

set "var=%random:~-1%"
:first
ping localhost -n 1 >nul
for /f "tokens=*" %%_ in ("%var%") do (
<nul set/p "=%%_ "
echo.&echo.
)
if ["%cont%"]==["9"] (call:llen "0") else (set/a "cont+=1"&goto:first)
goto:first

:llen
set "cont=%*"
for /l %%_ in (9,-1,0) do (set "var=!var:%%_=%random:~-1%!")
set "var=%var% %random:~-1%"
goto:first

--------- a progress bar ------

@echo off
title %~n0
set var=ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
for /l %%@ in (20,1,50) do (for /l %%_ in (1,1,8) do (call:script %%~@ %%~_))
pause>nul
:script
mode con cols=%~1 lines=1
color 0%~2
<nul set/p "=%var%"
set var=%var%Û
ping localhost -n 1 >nul
goto:eof

Post Reply