I am trying to stop screen flicker when it comes to my batch program that is used to display a text file on the screen. It has to update and the only way I have come up with is to loop the program and clear the screen.
This is my current code.
::Begin the refresh loop
::---------------------------------------------------------------
:Refresh
type "%ud%\ChatTerminal\Msg.txt
Sleep 1
cls
Goto Refresh
:Break Refresh
::---------------------------------------------------------------
::Refresh Loop Ends
::---------------------------------------------------------------
After some research I came to this post:
How do I remove flickering from a batch file animation?
The issue is that I would not know where to start with the implementation.
The escape character for VT sequences can be defined using:
For /F %%e in ('echo prompt $E^|cmd')Do set "\E=%%e"
Depending on the format and contents of each .txt file, flicker free animation could be as simple as returning the cursor to screen home between each 'frame':
<nul set /p "=%\E%[1;1H"
Edit
Should the source file/s be of differing line lengths or line counts, then each line needs to be read in and the VT sequence %\E%[K prepended to clear the remainder of the line and %\E%[0J after each file to clear the remainder of the console screen from the cursor location.
An example, which creates files to animate:
(Note: %\E%[E emits a line feed )
Anim.bat
#Echo off & CD /D "%~dp0"
For /f %%e in ('Echo Prompt $E^|cmd') Do set "\E=%%e"
<nul Set /P "=%\E%[?25l"
Set /A "delay=4", "Files=0","FC=1"
Setlocal EnableExtensions EnableDelayedExpansion
For %%i in (5 6 7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7 6 5)Do (
Set /A Files+=1
Call :CreateCube %%i "infile!Files!.txt"
)
For /L %%i in ()Do (
for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!") do set /a "t2=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100, tDiff=t2-t1"
if !tDiff! lss 0 set /a tDiff+=24*60*60*100
if !tDiff! geq !delay! (
Set /A "FC=FC %% Files + 1"
<nul Set /P "=%\E%[1;0H"
If !FC! GTR 10 (If !Offset! GTR 1 Set /A "Offset-=1")Else Set "offset=!FC!"
(For /f "Delims=" %%G in (infile!FC!.txt)Do <nul set /P "=%\E%[K%\E%[!offset!G%%G%\E%[E") > Con
<nul Set /P "=%\E%[0J"
set /a t1=t2
)
)
:CreateCube <size>
:# golfed script for outputting a shaded multi color cube
:# https://codegolf.stackexchange.com/a/224741/92319
#echo off&Cls&Set $=Set &CHCP 65001 > nul
If "%~1"=="" (Echo(%~n0 Integer Outfile.ext&Exit /B)
If "%~2"=="" (Echo(%~n0 Integer Outfile.ext&Exit /B)
(<Nul Set /p "=%\E%7")>"%~2"
%$%/A x=%1,h=x*2,z=0
%$%F=For /L %%a in (1 1 &%$%P=^<nul set/p &%$%C= If %%y LEQ %1
((%f:a=y%!h!)Do (%$%/a w=x-z
%F%!w!)Do %P%"=%\E%7 "
%F%!z!)Do%C%(%P%"=%\E%[38;2;0;120;%%a0m_|")Else %P%"=%\E%[4m%\E%[38;2;120;0;%%a0m\\%\E%[0m"
%F%%1)Do%C%(%P%"=%\E%[38;2;120;0;%%a0m▲▼")Else %P%"=%\E%[38;2;0;120;%%a0m_\"
%C:EQ=SS%(%$%/A z+=1)Else%C:If=If not%%$%/A z-=1)&Echo(%\E%[0m))>"%~2"
Note: the time elapsed operation used for framerate originates from Dave Benhams snake.bat
Implementation of framerate control in a repeating for /l infinate loop is strongly recommended to facilitate a smooth animation - failure to do so will result in the animation appearing jagged / choppy as it occurs at a pace the eye cant follow
T3RR0R's solution overwrites existing lines without deleting the rest of the old line. So when the new line is shorter, the rest of the old line keeps showing.
That could be solved by writing the file line by line, deleting the rest of the line. Sadly that slows things down and thus re-introduces the flicker (at least for files with more than one line).
As an alternative, only write the file, if it has changed. It still flickers, but now just when the file is updated. After displaying the file, unset the archive attribute. Whenever Windows writes to the file, it sets the attribute again, which we use to determine if the file has changed.
#echo off
set "file=%ud%\ChatTerminal\Msg.txt"
:loop
attrib "%file%"|findstr /b "A" >nul && (
cls
type "%file%"
attrib "%file%" -a
)
timeout 1 >nul
goto :loop
Bonus: this doesn't use Escape codes, so it runs on every Windows version (possibly there are a few deprecated Windows versions that didn't have timeout by default, but it can be replaced with ping when needed)
Seems like all you are trying to do is TAIL a file and print the those new lines to the screen. You can use this method to accomplish that.
#echo off
call :Read <"file.txt"
GOTO :EOF
:Read
set "line="
set /p "line="
if defined line (
echo %line%
)
goto :Read
Related
I'm a biologist, with no coding knowledge, trying to create a script that reads every *rprt.txt file in a folder.
In line 11 of each file, the fifth word is a number, If that number is 6000<number<14000 then I want to read the fifth word in line 13 and if that number is greater than 600. Copy the file into another folder in that directory.
At this point I've tried a lot of things. I know the next code is exiting the loop but is the best I got.
#echo off
for %%f in (*rprt.txt) do set "name=%%f" &goto first
:first
for /F "skip=10 tokens=5" %%i in (%name%) do set "var1=%%i" &goto nextline
:nextline
for /F "skip=12 tokens=5" %%i in (%name%) do set "var2=%%i" &goto nextline2
:nextline2
if %var1% geq 6000 (if %var2% geq 600 echo.%name% >> valid.txt)
I've also tried this to test the for loop but I don't understand what's wrong. This prints "echo is off" 3 times
#echo off
for %%f in (*rprt.txt) do (set "name=%%f" & echo %name% >> valid.txt)
#ECHO OFF
SETLOCAL
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
FOR %%e IN ("%sourcedir%\*rprt.txt") DO (
rem %%e has filename
SET "line11="
FOR /f "usebackqskip=10tokens=5" %%y IN ("%%e") DO IF NOT DEFINED line11 (
SET "line11=y"
SET "line13="
FOR /f "usebackqskip=12tokens=5" %%o IN ("%%e") DO IF NOT DEFINED line13 (
SET "line13=y"
IF %%y gtr 6000 IF %%y lss 14000 IF %%o gtr 600 ECHO COPY "%%e" "%destdir%"
)
)
)
GOTO :EOF
Always verify against a test directory before applying to real data.
Note that if the filename does not contain separators like spaces, then both usebackq and the quotes around "%%e" can be omitted.
I'm assuming that the values in token 5 of the two lines are guaranteed numeric.
You were definitely on the right track, but the code for validating that something is a number can get kinda weird if you're not used to seeing it (in this case, I remove everything that isn't a digit and then return 1 if there's anything remaining) and the way that GTR and LSS work can also be confusing since it's based on ASCII values so words report as greater than numbers.
The script expects the reports to be in their own folder and the output folder to be in its own folder, and both of these folders should be in the same folder as the script, as opposed to the script being in the same folder as the input files.
#echo off
setlocal enabledelayedexpansion
set "input_directory=%~dp0\input"
set "output_directory=%~dp0\output"
pushd "%input_directory%"
for %%A in (*_rprt.txt) do (
for /f "tokens=5" %%B in ('findstr /n /r "^" "%%~A" ^| findstr "11:"') do set "line_11_num=%%B"
for /f "tokens=5" %%B in ('findstr /n /r "^" "%%~A" ^| findstr "13:"') do set "line_13_num=%%B"
call :isNumber !line_11_num! n[11]
call :isNumber !line_13_num! n[13]
set /a "valid_report=!n[11]!+!n[13]!"
if "!valid_report!"=="0" (
if !line_11_num! GTR 6000 if !line_11_num! LSS 14000 (
if !line_13_num! GTR 600 (
copy "%%~A" "%output_directory%"
)
)
)
)
exit /b
::------------------------------------------------------------------------------
:: Determines if a given string is a positive integer
::
:: Arguments: %1 - The value to check
:: %2 - The variable to store the result in
:: Returns: 0 if the number is a positive integer, 1 otherwise
::------------------------------------------------------------------------------
:isNumber
set "is_number=0"
for /f "delims=0123456789" %%A in ("%~1") do set "is_number=1"
set "%~2=%is_number%"
exit /b
The files and lines processed by for /F command must be processed completelly until the file ends; you can not "cut" the process at the middle with a goto command because the whole process is cancelled.
This means that all lines of all files must be processed with nested for /F commands and you must insert some type of control in order to "omit" the rest of lines that are not the 11 or 13. If the files are numerous or very large, this can take some time.
You can also take just the lines 11 and 13 via findstr commands, but anyway the execution of a couple of findstr commands connected via a pipe also takes some time.
You must be aware that any variable that takes its value inside a compound command (like for or if) must be accessed using !delayedExpansion! instead of %standardExpansion%. There are a lot of questions/answers in this site about this point.
My solution below takes a different approach: it reads just the first 13 lines of each file via a redirection instead of for /F command or findstr. If the files are few and small, this method would be similar in time to the other ones. However, I think this method is simpler and easier to understand.
#echo off
setlocal EnableDelayedExpansion
rem Read every *rprt.txt file in this folder
for %%f in (*rprt.txt) do (
rem Read line 11 and 13 of this file via a redirection
< "%%f" (
rem Skip first 10 lines
for /L %%i in (1,1,10) do set /P "dummy="
rem Read line 11 and line 13
set /P "line11="
set /P "dummy="
set /P "line13="
)
rem Get the number in line 11 and compare it
for /F "tokens=5" %%i in ("!line11!") do set "num=%%i"
if 6000 lss !num! if !num! lss 14000 (
rem Get the number in line 13 and compare it
for /F "tokens=5" %%i in ("!line13!") do set "num=%%i"
if !num! gtr 600 copy "%%f" anotherFolder
)
)
I want to create an automated testing array in Windows Command using a single code statement as the VALUE for each testing array record. Here is what the array definition looks like for the first two records in the $code_test[xx] array:
set $code_test[00]=if 5 lss 10 (echo IT WORKED)
set $code_test[01]=if 5 lss 10 (echo BUG OFF)
I want to execute the VALUE of each $code_test[xx] array record (which is a test code statement) using a for /l loop like this:
for /l %%g in (0,1,1) do (
echo $code_test[0%%g]
!$code_test[0%%g]!
echo.
)
The complete code is:
#echo off
setlocal enabledelayedexpansion
set $code_test[00]=if 5 lss 10 (echo IT WORKED)
set $code_test[01]=if 5 lss 10 (echo BUG OFF)
for /l %%g in (0,1,1) do (
echo $code_test[0%%g]
!$code_test[0%%g]!
echo.
)
echo.
pause
When I execute the complete code I get the following error message when the !$code_test[0%%g]! line of code is executed:
'if' is not recognized as an internal or external command, operable
program or batch file
I've read the excellent article here about how the IF command is parsed, but I don't see anything that jumps out at me as to why my code is failing. Is it even possible to do what I'm trying to accomplish?
Any Help Is Appreciated!
UPDATE:
I discovered that #sst is correct when I used the set command in the set $code_test[01]=if 5 lss 10 (set /a $var1+=1)
line of code:
#echo off
setlocal enabledelayedexpansion
set $var1=0
set $code_test[00]=if 5 lss 10 (echo IT WORKED)
set $code_test[01]=if 5 lss 10 (set /a $var1+=1)
for /l %%g in (0,1,1) do (
echo $code_test[0%%g]
cmd /c !$code_test[0%%g]!
echo $var1 = !$var1!
echo.
)
echo.
pause
The set /a $var1+=1 command didn't increment the value of $var1 as expected. In fact, it places a "1" in front of the $var1 label when the line of code echo $var1 = !$var1! executes. I haven't tried the solution offered by #Magoo yet. I'd really like to use the cmd /c solution instead of calling a subroutine. Is there anything I can do to make the set command work with the cmd /c option?
It can not work the way you tried, because the IF command is detected and handeled in phase 2.
But with delayed expansion it is too late.
This problem occurs only for the commands IF, FOR and REM.
´CALL %%$code_test%%` works in many cases, but fails also for the three commands and for code blocks.
It's unclear why it fails in that case, as the commands are parsed in phase 2 but they are not recognized.
The solution of #stephan uses a new cmd instance, it has the drawback, to lose all variable modifications every time the cmd instance finishes.
The solution of #Magoo uses therefore percent expansion, that should work in nearly all cases without problems.
#echo off
setlocal enabledelayedexpansion
set $code_test[00]=if 5 lss 10 (echo IT WORKED)
set $code_test[01]=if 5 lss 10 (echo BUG OFF)
for /l %%g in (0,1,1) do (
SET "$code_test=!$code_test[0%%g]!
CALL :test_code
echo.
)
echo.
GOTO :EOF
:test_code
%$code_test%
GOTO :eof
Another approach.
you seem to need another layer of parsing:
#echo off
setlocal enabledelayedexpansion
set $code_test[00]=if 5 lss 10 (echo IT WORKED)
set $code_test[01]=if 5 lss 10 (echo BUG OFF)
for /l %%g in (0,1,1) do (
echo $code_test[0%%g]
cmd /c !$code_test[0%%g]!
echo.
)
Edit (just for completeness):
found another way to do it (without a subroutine):
#echo off
setlocal enabledelayedexpansion
set $code_test[00]=if 5 lss 10 (echo IT WORKED)
set $code_test[01]=if 5 lss 10 (echo BUG OFF)
for /l %%g in (0,1,1) do (
echo $code_test[0%%g]
for /f "delims=" %%a in ('%%$code_test[0%%g]%%') do #set "result=%%a"
echo !result!
echo.
)
The trick is: for executes the ('...') part in a separate cmd process (as cmd /c ...) but captures the output into the main process.
Works both with !$code_test[0%%g]! and %%$code_test[0%%g]%%.
Although it doesn't work with if 5 lss 10 (set result=IT WORKED) because there is no output to capture (the set is only done with the do clause).
As I am not an expert in script command and I am getting stuck on this script, I am asking the community for some help.
As for my problem I tried the following (see code below ) in order to change a character in a textfile on a specific location. By using For /F I was hoping to readout the entire file to a backup copy, and just change the wanted location to the new value by using an IF. However I noticed that when I put the token parameter to tokens=6 it wouldn't copy the entire file to the new location. so I changed this to tokens=*. However with this the entire row on the 74th line is changed. :s and with this I also found out that ENTERS and specific characters as "!" are not copied to the backup file.
Now i was hoping that you could help me change this character on location line 74 , token 6 without further resulting in any change of the specific text file.
thanks for any advise.
#echo off
CLS
setlocal enabledelayedexpansion
set ORIGINALFILE=test.file.txt
set MODIFIEDFILE=temp1.txt
set MODIFIEDFILE2=temp_backup.txt
set SEARCHVALUE=0
set REPLACEVALUE=1
set OUTPUTLINE=
set linenumber=0
::for demo purpose make cop of original file as original will be overwritten
copy %ORIGINALFILE% %MODIFIEDFILE2%
del temp1.txt
echo "all set"
timeout /t 2 /nobreak >nul
::everything is set now change the 6th item on the line 74 to a "1"
FOR /f "tokens=* delims=," %%G in ('"type %ORIGINALFILE%"') do (
set /a linenumber=!linenumber!+1
SET string=%%G
if !linenumber! EQU 61 (
SET modified=!string:%SEARCHVALUE%=%REPLACEVALUE%!
echo !linenumber!
) else (
echo !linenumber!
SET modified=!string!
)
echo !modified! >> %MODIFIEDFILE%
)
#ECHO OFF
SETLOCAL
set ORIGINALFILE=q34614930.txt
set MODIFIEDFILE=u:\temp1.txt
set MODIFIEDFILE2=u:\temp_backup.txt
set SEARCHVALUE=0
set REPLACEVALUE=1
::for demo purpose make cop of original file as original will be overwritten
copy %ORIGINALFILE% %MODIFIEDFILE2% >NUL 2>nul
REM echo "all set"
REM timeout /t 2 /nobreak >nul
::everything is set now change the 6th item on the line 5 to a "1"
(
FOR /f "tokens=1*delims=:" %%a in ('findstr /n /r ".*" "%ORIGINALFILE%"') do (
IF "%%a"=="5" (
FOR /f "tokens=1-6*delims=," %%A IN ("%%b") DO echo(%%A,%%B,%%C,%%D,%%E,%replacevalue%,%%G
) ELSE ECHO(%%b
)
)>"%MODIFIEDFILE%"
GOTO :EOF
I used a file named q34614930.txt containing some test data for my testing. I also changed the filenames to suit mys system.
In the absence of representative data, I use the following and replaced column 6 in line 5.
line 1,col2,col3,col4,col5,col6,col7,col8
line 2,col2,col3,col4,col5,col6,col7,col8
line 4,col2,col3,col4,col5,col6,col7,col8
line 5,col2,col3,col4,col5,col6,col7,col8
line 6,col2,col3,col4,col5,col6,col7,col8
Result
line 1,col2,col3,col4,col5,col6,col7,col8
line 2,col2,col3,col4,col5,col6,col7,col8
line 4,col2,col3,col4,col5,col6,col7,col8
line 5,col2,col3,col4,col5,1,col7,col8
line 6,col2,col3,col4,col5,col6,col7,col8
Without representative data, we're guessing.
I have no experience with command prompt whatsoever, but I'd like to make a batch script (for fun and learn) that would print a text file from a given location, line by line, with a 1 second delay.
I would also want it to be able to pause/unpause when I press a designated key (ex: space) and feed me an extra line (on top of those already programmed to run) when I press another key (ex: enter).
I know I can add a 1 second delay by pinging localhost ping -n 5 127.0.0.1 > nul
And I know I can see the content of a text file using more text.txt, but I don't know how to iterate through an entire text file until EOF is met and I don't know how to pause/resume and feed extra line.
Hope it doesn't sound stupid or out of scope in this context, but it's just something that interests me right know and I know a lot people here have the knowledge to do this.
1) If you have experience in programming, you will know using a for loop is the most common way to do things one by one, e.g. line by line.
2) You can simply use ping localhost -n 2 >nul for 1 second delay, the 2 in the ping is not indicating 2 seconds, but 1 second instead. (I have no idea about that, just get used to it)
3) You can't pause/unpause when cmd is pinging, I mean there's no way to force the program to pause/unpause because the delay process is executed in just a line of code! Or you can magically add some code into it like ping localhost -n 2 pause while(KeyDown(SPACE)) >nul (just kidding :) )
4) Extra lines? Hmm... Remember batch is not a powerful language so... Yeah
Here is a simple code to print text line by line each second in a .txt file
for /f %%a in (your_text.txt) do (
echo %%a
ping localhost -n 2 >nul
)
You could do it synchronously with choice /t 1 (for a 1-second timeout) and some key other than Spacebar. Perhaps P for Pause?
#echo off
setlocal
set "textfile=notes.txt"
echo Hit P to pause / resume, Q to quit.
echo;
for /f "tokens=1* delims=:" %%I in ('findstr /n "^" "%textfile%"') do (
echo(%%J
choice /t 1 /c €pq /d € >NUL
if errorlevel 3 exit /b 0
if errorlevel 2 (
pause >NUL
ping -n 1 -w 750 169.254.1.1 >NUL
)
)
exit /b 0
Unfortunately, choice only allows a-z, A-Z, 0-9, and extended characters 128-254. There's no way to make it listen for Enter or Space. And choice is the only Windows command of which I'm aware that'll accept a single keypress and do something meaningful based on which key was pressed.
I think you'll have to use some sort of compiled language (or possibly PowerShell with a .NET class?) to listen for keypress events on the console. You could probably do it in JavaScript, but you'd have to display your output in a web browser or HTA window.
A "scrolling editor"? It is a crazy idea, isn't it? I LIKE IT! ;-) I adopted your project and add some points...
#echo off
rem ScrollEditor.bat: "dynamic" very simple line editor
rem Antonio Perez Ayala aka Aacini
if "%~1" neq "" if "%~1" neq "/?" goto begin
echo ScrollEditor.bat filename.ext
echo/
echo File lines will be continually scrolling, one per second.
echo/
echo You may pause the scroll via P key. In the "paused" state, the last displayed
echo line is named "current line", and the following commands are active:
echo/
echo #L Return/advance the listing to line #; continue the scroll from there.
echo [#]D Delete [from previous line # up to] current line.
echo I Insert lines after current line; end insert with *two* empty lines.
echo P End "paused" state; continue the scroll from current line on.
echo E End edit and save file, keep original file with .bak extension.
echo Q Quit edit, not save file.
goto :EOF
:begin
if not exist %1 echo File not found & goto :EOF
rem Load file lines into "line" array
set /P "=Loading file... " < NUL
setlocal DisableDelayedExpansion
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %1') do (
set "line[%%a]=%%b"
set "lastLine=%%a"
)
echo last line: %lastLine%
echo To pause scrolling, press: P
echo/
setlocal EnableDelayedExpansion
set "validCommands=LDIPEQ"
set currentLine=1
:command-P End "paused" state
:ScrollLine
if %currentLine% gtr %lastLine% (
set "currentLine=%lastLine%"
echo EOF
goto GetCommand
)
set "num= %currentLine%"
echo %num:~-4%: !line[%currentLine%]!
set /A currentLine+=1
choice /C PC /N /T 1 /D C >NUL
if errorlevel 2 goto ScrollLine
rem Enter paused state
set /A currentLine-=1
:GetCommand
echo/
set /P "command=Command [#L,#D,I,P,E,Q]? "
set "letter=%command:~-1%"
if "!validCommands:%letter%=!" equ "%validCommands%" goto GetCommand
goto command-%letter%
:command-L Go to line #; continue scrolling
set "currentLine=%command:~0,-1%"
goto ScrollLine
:command-D Delete from line # to current line
set "prevLine=%command:~0,-1%"
if not defined prevLine set "prevLine=%currentLine%"
rem Move lines after last deleted one into deleted lines
set /A currentLine+=1, newCurrent=prevLine-1, lines=currentLine-prevLine
for /L %%j in (%currentLine%,1,%lastLine%) do (
set "line[!prevLine!]=!line[%%j]!"
set /A prevLine+=1
)
set /A currentLine=newCurrent, lastLine=prevLine-1
if %currentLine% equ 0 set "currentLine=1"
echo %lines% line(s) deleted (current=%currentLine%, last=%lastLine%)
goto GetCommand
:command-I Insert lines after current one
echo End insert with *two* empty lines
echo/
rem Read new lines into "ins" array
set "newLine=%currentLine%"
:insertLine
set "line="
set /A newLine+=1
set "num= %newLine%"
set /P "line=+%num:~-3%: "
set "ins[%newLine%]=!line!"
rem The most complex part: end in two empty lines...
if not defined line (
set /A newLine+=1
set "num= !newLine!"
set /P "line=+!num:~-3!: "
if defined line (
set "ins[!newLine!]=!line!"
) else (
set /A newLine-=2
)
)
if defined line goto insertLine
rem Move old lines to new place to make room for new lines
set /A lines=newLine-currentLine, currentLine+=1, newLast=lastLine+lines
for /L %%j in (%lastLine%,-1,%currentLine%) do (
set "line[!newLast!]=!line[%%j]!"
set /A newLast-=1
)
rem Insert new lines in old place
for /L %%j in (%currentLine%,1,%newLine%) do set "line[%%j]=!ins[%%j]!"
set /A lastLine+=lines, currentLine=newLine
echo %lines% line(s) inserted (current=%currentLine%, last=%lastLine%)
goto GetCommand
:command-E End edit, save file
echo Saving file...
move /Y %1 "%~N1.bak"
(for /L %%i in (1,1,%lastLine%) do echo(!line[%%i]!) > %1
:command-Q Quit edit
echo End edit
This program have multiple problems: don't check for valid input in commands, may have problems with special Batch characters and if the first character of a line is a colon, eliminate it. However, it is a good starting point for this project!
Perhaps you may be interested in this similar project.
So, I am currently making a "loading screen", and to possibly save some space in my coding, I want to know if you could edit a line already outputted. I would have maybe a bracket [] as one stage of loading, so would it be possible to put one bracket, then wait and see if user presses C (for continue) for 1-2 seconds, and if not go to the next stage ([][])? I currently have a script where [] is set as load and for every stage, I do CLS and then echo %LOAD%[].
In addition, what if I just want to do a status update on a line, such as:
Checking status...
Loading server...
and then
Checking status... OK
Loading server... done
Bonus points if you can find me a character like █ that is compatible with Batch.
You can ommit the CLS and recreating the full screen with the help of set /p, as set /p doesn't output a newline, you can append text.
Normally set /p is for assigning text to a variable inputted by a user, but if you use redirection from NUL it simply outputs text.
#echo off
for /L %%n in (1 1 5 ) do (
<nul set /p ".=[]"
ping -n 2 localhost > nul
)
echo(
echo The end
The status update you asked for, can be handled the same way, as it only appends something to the line.
If you want to change parts of the line or the complete line, you need to move the cursor back or to the beginning of the line.
Both can be done with the backspace character or the carriage return character.
This is a sample which counts on a fixed screen location
setlocal EnableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
for /L %%n in (1 1 1000) do (
<nul set /p ".=%%n!CR!"
)
Creating a blockchar like █ can be done with
setlocal EnableDelayedExpansion
for /F "usebackq tokens=1" %%c in (
`forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo 0xde"`) do (
set BlockChar=%%c
)
echo %BlockChar%
Thanks to dbenham Generate nearly any character, including TAB, from batch