Skip to main content

How to Loop Through Lines in a String Variable in Batch Script

A common task in scripting is to capture the multi-line output of a command into a single string variable and then process each of those lines individually. For example, you might get a list of services or files that you need to iterate through. Unlike reading directly from a file or a command, this requires a specific technique to make the FOR /F loop read from a variable instead of an external source.

This guide will teach you the standard and most effective method for looping through the lines of a string variable by using the ECHO command to pipe the variable's content into a FOR /F loop.

The Challenge: FOR /F Doesn't Read Variables Directly

The FOR /F command is the primary tool for parsing text, but its IN() clause is designed to work with files, commands, or literal strings, not the content of a variable.

Example of script with error:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "MyString=Line 1
Line 2"

REM This will NOT work as expected.
FOR /F "delims=" %%L IN (!MyString!) DO (
ECHO Line: %%L
)
note

This fails because the IN() clause interprets the variable's content as a filename or a literal string in a way that doesn't preserve the line breaks.

The Core Method: ECHO ... | FOR /F

The standard and most reliable solution is to use the ECHO command to "print" the content of your variable, and then use a pipe (|) to redirect that output into the FOR /F loop. This makes the loop behave as if it were reading the output of a command.

Syntax: ECHO !MyMultiLineString! | FOR /F "delims=" %%L IN ('findstr .') DO ( ... )

  • ECHO !MyMultiLineString!: Prints the entire multi-line string to the console.
  • |: The pipe sends this output as input to the next command.
  • FOR /F "delims=" %%L IN ('findstr .'): This is a special form of the FOR /F loop.
    • IN ('findstr .'): Instead of a file or a specific command, we use findstr . (or a similar command) to read from the standard input stream, which is now receiving the piped output from ECHO. findstr . is a robust choice that preserves empty lines.

Basic Example: A Simple Multi-line String

This script defines a multi-line string and then uses the ECHO | FOR /F method to process each line individually.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

REM --- Define a multi-line string ---
SET "Line1=First line of text"
SET "Line2="
SET "Line3=Third line of text"
SET "MyString=!Line1!
!Line2!
!Line3!"

ECHO --- Original Multi-line String ---
ECHO !MyString!
ECHO ------------------------------------
ECHO.
ECHO --- Looping through each line ---
FOR /F "delims=" %%L IN ('ECHO !MyString! ^| findstr /N "^"') DO (
SET "line=%%L"
ECHO Line content: [!line:*:=!]
)
ENDLOCAL
note

Using findstr /N "^" prefixes each line with a number, making it extremely robust for handling empty lines. !line:*:=! then removes this prefix.

Output:

--- Original Multi--line String ---
First line of text

Third line of text
------------------------------------

--- Looping through each line ---
Line content: [First line of text]
Line content: []
Line content: [Third line of text]

Let's see how the ECHO | FOR /F method works:

  1. SET "MyString=...!": The multi-line string is created. Delayed expansion (!) is crucial here to correctly handle the line breaks and build the variable.
  2. ECHO !MyString!: This command prints the entire content of the variable, including the line breaks, to a temporary output stream.
  3. |: The pipe operator takes the output from the ECHO command and redirects it to become the standard input for the command on the right.
  4. findstr /N "^": findstr reads from this standard input. The /N "^" part numbers every line it receives.
  5. FOR /F ... IN ('...'): The FOR /F loop executes the findstr command and captures its output. It then processes this captured, multi-line output one line at a time, as it would with any other command.

Common Pitfalls and How to Solve Them

Problem: Delayed Expansion Corrupts the String

This technique relies heavily on Delayed Expansion.

  • You must use SETLOCAL ENABLEDELAYEDEXPANSION.
  • You must use ! to define and echo the multi-line string.

If you try to use %MyString%, it will be expanded when the command is parsed, and the line breaks will be converted into spaces, collapsing your multi-line string into a single line.

Problem: The String Contains Special Characters (&, |, etc.)

This is the most significant weakness of this method. When you ECHO !MyString!, the command interpreter will parse the string for special characters before the FOR loop ever sees it. If your string contains & or |, it will break the command.

Example of script with error:

SET "MyString=apples & bananas"
ECHO !MyString! | FOR ...

This will fail because & is the command separator.

Solution: Use a Temporary File (The Most Robust Method)

For strings that might contain special characters, the only truly safe "pure-batch" method is to write the variable's content to a temporary file and then have the FOR /F loop read that file.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "MyString=apples & bananas
pears | oranges"
SET "TEMP_FILE=%TEMP%\%RANDOM%.txt"

ECHO !MyString! > "%TEMP_FILE%"

FOR /F "usebackq delims=" %%L IN ("%TEMP_FILE%") DO (
ECHO Line: %%L
)

DEL "%TEMP_FILE%"
ENDLOCAL
note

This avoids the ECHO parsing issue entirely and is the recommended approach for handling unpredictable or user-provided multi-line strings.

Practical Example: Capturing and Processing DIR Output

This script captures the output of a DIR /B command into a single variable, and then loops through that variable to process each filename.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

ECHO --- Capturing a list of TXT files ---
SET "FileList="
FOR /F "delims=" %%F IN ('DIR *.txt /B') DO (
REM Append the filename and a line break to the variable
SET "FileList=!FileList!%%F
"
)

ECHO.
ECHO --- FileList variable captured. Now looping through it: ---
FOR /F "delims=" %%L IN ('ECHO !FileList!') DO (
ECHO Processing file from variable: "%%L"
)

ENDLOCAL

Conclusion

Looping through the lines of a string variable is an advanced technique that demonstrates the power of piping and command redirection in batch scripting.

  • The standard method is to pipe the output of ECHO into a FOR /F loop: ECHO !MyVar! | FOR /F ....
  • This technique requires Delayed Expansion (!) to work correctly with the multi-line variable.
  • Be aware that this method is not safe for strings containing special characters like & or |.
  • For unpredictable or complex strings, the most robust solution is to write the variable to a temporary file and then have FOR /F read the file.