How to read and print contents of text file line by line?

Solution 1:

Let us assume the text file TestFile.txt should be output line by line 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 if used internet browser does not remove them.
        
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=" %%I in ("TestFile.txt") do (
    echo(%%I
    %DelayCommand% >nul
)
endlocal
pause

The strange looking character ¿ after eol= is an inverted question mark with hexadecimal Unicode value 00BF used to output third line correct. A line with an inverted question mark at beginning would not be output because of this redefinition of end of line character.

This batch file code is not designed to output any type of text file with any type of character encoding independent on which characters contains the text file. 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^= %%I in ("TestFile.txt") do (
    echo(%%I
    %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 to get interpreted by cmd.exe the string usebackq delims= eol= as one argument string for for /F.

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/%%I 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^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "TestFile.txt" 2^>nul') do (
    set "Line=%%I"
    setlocal EnableDelayedExpansion
    echo(!Line:*:=!
    endlocal
    %DelayCommand% >nul
)
endlocal
pause

The entire line with line number and colon output by FINDSTR executed in a separate command processes started by FOR with %ComSpec% /c and the command line within ' as additional arguments is assigned to loop variable I which is assigned next to environment variable Line.

Then delayed expansion is enabled as 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 the output of the 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 just 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 /?

Solution 2:

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.

Solution 3:

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