Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
So, I have no clue on how to have CMD echo lines from a *.txt text file one at a time with a tiny delay to make it seem like it's processing.
Is this even possible with a batch alone?
I've tried doing research, but I can't find sufficient text manipulation to be able to do this, but I do know how to make a pause between each command and how to do loops.
Let us assume to output is line by line the text file TestFile.txt
which is an ANSI encoded text file with just ASCII characters containing this text:
Line 1 is with nothing special. Next line 2 is an empty line.
;Line 3 with a semicolon at beginning.
Line 4 has leading spaces.
Line 5 has a leading horizontal tab.
Line 6 is with nothing special. Next line 7 has just a tab and four spaces.
Line 8 is ! with exclamation marks ! in line!
? Line 9 starts with a question mark.
: Line 10 starts with a colon.
] Line 11 starts with a closing square bracket.
The batch file below outputs this text file line by line with one second delay between each line with the exception of second line which is completely empty.
@echo off
title Read line by line with delay
setlocal EnableExtensions DisableDelayedExpansion
rem Use command TIMEOUT by default for 1 second delay. But use
rem PING in case of TIMEOUT does not exist as on Windows XP.
set "DelayCommand=%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK"
if not exist %SystemRoot%\System32\timeout.exe set "DelayCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
for /F "usebackq eol= delims=" %%A in ("TestFile.txt") do (
echo(%%A
%DelayCommand% >nul
)
endlocal
pause
The strange looking character after eol=
is the form-feed control character with hexadecimal code value 0C used to output third line correct. A line with a form-feed at beginning would not be output because of this redefinition of end of line character.
This code is not designed to output any type of text file with any type of character encoding independent on which characters the text file contains. The Windows command line environment is not designed for output of any text file.
It is also possible to use a different, unquoted syntax to specify the FOR options delims
, eol
and usebackq
to define an empty list of delimiters and no end of line character:
@echo off
title Read line by line with delay
setlocal EnableExtensions DisableDelayedExpansion
rem Use command TIMEOUT by default for 1 second delay. But use
rem PING in case of TIMEOUT does not exist as on Windows XP.
set "DelayCommand=%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK"
if not exist %SystemRoot%\System32\timeout.exe set "DelayCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
for /F usebackq^ delims^=^ eol^= %%A in ("TestFile.txt") do (
echo(%%A
%DelayCommand% >nul
)
endlocal
pause
Thanks goes to aschipfl for this alternate syntax of the three FOR options with using escape character ^
to escape the equal signs and spaces in not double quoted options string.
There is (
instead of a space as usually used to output also correct line 7 with just a tab and some normal spaces. See also DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/. echo/%%A
as preferred by me does not correct output line 9 starting with a question mark.
It is not possible to define with an option that FOR does not ignore empty lines. But it is possible with FIND or FINDSTR to output a text file with all lines with a line number at beginning and so having no empty line anymore. The line number is enclosed in square brackets (FIND) or separated with a colon (FINDSTR) from rest of the line. It would be possible to assign to loop variable only the string after first sequence of ]
or :
after line number which in most cases means the entire line as in text file. But if a line in text file starts by chance with ]
or :
, FOR would remove this delimiter character too. The solution is this code:
@echo off
title Read line by line with delay
setlocal EnableExtensions DisableDelayedExpansion
rem Use command TIMEOUT by default for 1 second delay. But use
rem PING in case of TIMEOUT does not exist as on Windows XP.
set "DelayCommand=%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK"
if not exist %SystemRoot%\System32\timeout.exe set "DelayCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
for /F delims^=^ eol^= %%A in ('%SystemRoot%\System32\findstr.exe /N "^" "TestFile.txt" 2^>nul') do (
set "Line=%%A"
setlocal EnableDelayedExpansion
echo(!Line:*:=!
endlocal
%DelayCommand% >nul
)
endlocal
pause
The entire line with line number and colon output by FINDSTR in a separate command processes started by FOR with cmd /C
and the command line within '
is assigned to loop variable A
which is assigned next to environment variable Line
.
Then delayed expansion is enabled needed for next line which results in pushing address of current environment variables list on stack as well as current directory path, state of command extensions and state of delayed expansion before creating a copy of the current environment variables list.
Next the value of environment variable Line
is output, but with substituting everything up to first colon by nothing which results in output of real line as stored in text file without the line number and the colon inserted at beginning by FINDSTR.
Finally the created copy of environment variables list is deleted from memory, and previous states of delayed expansion and command extension are popped from stack and set as well as the current directory path is set again as current directory and previous address of environment variables list is restored to restore the list of environment variables.
It is of course not very efficient to run for each line in text file the commands setlocal EnableDelayedExpansion
and endlocal
doing much more than justs enabling/disabling delayed expansion, but this is necessary here to get lines with an exclamation mark correct assigned to environment variable Line
and process next correct the value of Line
. The efficiency loss is not really problematic here because of the delay of one second between output of each line.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
findstr /?
for /?
if /?
ping /?
rem /?
set /?
setlocal /?
Despite your question being off topic, I have decided to include this because, there are already two answers and it can be achieved using a single line.
From a batch file:
@For /F Tokens^=1*Delims^=]^ EOL^= %%A In ('Find /N /V ""^<"C:\test.txt"') Do @Echo(%%B&>Nul PathPing 127.0.0.1 -n -q 1 -p 450
From the Command Prompt:
For /F Tokens^=1*Delims^=]^ EOL^= %A In ('Find /N /V ""^<"C:\test.txt"') Do @Echo(%B&>Nul PathPing 127.0.0.1 -n -q 1 -p 1350
Both examples do not omit empty lines from your source file, C:\test.txt
, which can be changed as required.
I have used PathPing
for the 'tiny delay', because it seems more controllable; to adjust the delay all you need to do is change the last number until you find your most pleasing output.
Give a try for this batch script :
@echo off
Title Read line by line with delay
set "InputFile=TestFile.txt"
set "delay=1" Rem Delay one seconds, you can change it for your needs
setlocal enabledelayedexpansion
for /f "tokens=*" %%A in ('Type "%InputFile%"') do (
set /a N+=1
set "Line[!N!]=%%A"
)
for /l %%i in (1,1,%N%) do (
echo !Line[%%i]!
Timeout /T %delay% /nobreak>nul
)
pause