Skip to main content

How to Read a Text File Line by Line in Batch Script

Processing the contents of a text file is a fundamental task in scripting. Whether you are reading a configuration file, parsing log data, or handling a list of inputs, you need a reliable way to read a file one line at a time. The standard and most powerful method for this in Windows Batch is the FOR /F command.

This guide will demonstrate the correct use of FOR /F for reading files, explain the common pitfalls you will encounter, such as skipping empty lines or mishandling special characters, and provide robust solutions for each.

The Command FOR /F

The FOR /F command is designed to loop through items in a file, a string, or the output of a command. When used with a file, it reads the file line by line and, for each line, allows you to execute one or more commands.

The basic syntax for reading a file is: FOR /F ["options"] %%V IN (filename.txt) DO (command)

  • %%V is the variable that receives the content of the line.
  • filename.txt is the file to be processed.

Basic Example: Reading and Echoing Each Line

Let's start with a simple text file named users.txt:

Alice
Bob
Charlie

Now, we'll use a basic FOR /F loop to read it.

@ECHO OFF
REM This script reads each line from users.txt and echoes it.

ECHO Reading the file...
FOR /F "delims=" %%a IN (users.txt) DO (
ECHO User: %%a
)
note

delims= is used here to ensure the entire line is read into the %%a variable, even if it contains spaces. Without it, FOR /F only captures the first "token" (word).*

Output:

Reading the file...
User: Alice
User: Bob
User: Charlie

Common Pitfalls and How to Solve Them

While the basic example works for simple files, it has several weaknesses that will cause problems with more complex data.

Problem: The Script Skips Empty Lines

FOR /F by default ignores any lines that are completely empty.

Let's see the error.

Consider this file, data_with_blanks.txt:

Line 1
Line 2

Line 4

Using our previous script on this file yields an incorrect result.

@ECHO OFF
REM This will fail to show the blank line.
FOR /F "delims=" %%i IN (data_with_blanks.txt) DO (
ECHO Line content: [%%i]
)

Output (The blank line is missing!)

Line content: [Line 1]
Line content: [Line 2]
Line content: [Line 4]

Solution

To fix this, we pipe the output of FINDSTR /N "^" into the FOR /F loop. This command finds all lines (even empty ones) and prefixes them with a line number and a colon, which FOR /F can then parse.

@ECHO OFF
REM Using FINDSTR to preserve empty lines.
FOR /F "tokens=1,* delims=:" %%a IN ('FINDSTR /N "^" data_with_blanks.txt') DO (
ECHO Line content: [%%b]
)
note

Here, "tokens=1,* delims=:" tells FOR /F to split each line at the first colon. The line number goes into %%a, and the rest of the line (the original content) goes into %%b.

Output (The blank line is now correctly processed as empty content)

Line content: [Line 1]
Line content: [Line 2]
Line content: []
Line content: [Line 4]

Problem: Lines Starting with a Semicolon are Ignored

By default, FOR /F treats the semicolon (;) as the end-of-line character (eol). Any line that begins with a semicolon is considered a comment and is skipped entirely.

Let's see the error.

Consider this file, config.txt:

config.txt
;This is a comment
Path=C:\Windows
;Another setting=disabled

A standard FOR /F loop will not see the lines starting with ;.

@ECHO OFF
REM This will skip the semicolon lines.
FOR /F "delims=" %%i IN (config.txt) DO (
ECHO Config line: [%%i]
)

Output (Note that only the non-comment line is processed)

Config line: [Path=C:\Windows]

Solution

Specify a different eol character in the FOR /F options. It's best to choose a character that you are certain will not appear at the start of any line.

@ECHO OFF
REM Setting the end-of-line character to a vertical bar |
FOR /F "eol=| delims=" %%i IN (config.txt) DO (
ECHO Config line: [%%i]
)

Output (All lines are now processed)

Config line: [;This is a comment]
Config line: [Path=C:\Windows]
Config line: [;Another setting=disabled]

Problem: Special Characters Like ! Are Lost or Cause Errors

This is a subtle but critical issue that occurs when Delayed Expansion is enabled. If a line contains an exclamation mark !, cmd.exe will try to interpret it as a variable, causing the character to be stripped or the script to crash.

Let's see the error.

Consider this file, passwords.txt:

passwords.txt
My password is Strong!Password

This script will fail to display the line correctly.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM This will fail because ! is a special character.
FOR /F "delims=" %%i IN (passwords.txt) DO (
ECHO Password is: %%i
)

Output (The ! is stripped because ENABLEDELAYEDEXPANSION is active)

Password is: StrongPassword

Solution

The safest way to handle this is to toggle delayed expansion on and off inside the loop. The line is first assigned to a variable with delayed expansion turned off, and then it's echoed with delayed expansion turned on.

@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
FOR /F "delims=" %%i IN (passwords.txt) DO (
SET "line=%%i"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO Password is: !line!
ENDLOCAL
)

Output (The line is displayed correctly)

Password is: My password is Strong!Password

Putting It All Together: A Robust Solution

By combining these techniques, we can create a highly reliable line-reading script that handles most edge cases. This example correctly processes a file with empty lines, semicolons, and special characters.

robust_data.txt
Value=100!
;A comment line

Another=Value

The script:

@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION

FOR /F "tokens=1,* delims=:" %%a IN ('FINDSTR /N "^" robust_data.txt') DO (
SET "line=%%b"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO Line content: [!line!]
ENDLOCAL
)

Output: All lines are processed correctly, preserving their original content

Line content: [Value=100!]
Line content: [;A comment line]
Line content: []
Line content: [Another=Value]

Conclusion

While reading a text file in a batch script may seem simple, several pitfalls can lead to incorrect behavior. By using the FOR /F command and understanding its options, you can avoid these common errors.

For reliable file processing, always remember to:

  1. Use delims= to capture the entire line.
  2. Pipe from FINDSTR /N "^" to preserve empty lines.
  3. Set the eol= option to avoid skipping lines that start with a semicolon.
  4. Carefully manage Delayed Expansion when lines may contain special characters like !.

Mastering these techniques will allow you to build robust and predictable batch scripts capable of handling any text-based data.