6. Loops with for¶
What & why¶
for is the workhorse of batch. It has five modes selected by a switch (for, for /L, for /D, for /R, for /F), and one syntax rule that catches everyone: the loop variable is written %%i in a script but %i at the prompt.
The %%i rule¶
At the interactive prompt you'd type for %f in (...) do echo %f. In a script, double the percent: %%f. If you ever see %f was unexpected at this time, you forgot to double it.
Loop variables are single letters, case-sensitive: %%f and %%F are different.
Mode 1: plain for — iterate a list / files¶
rem Literal list:
for %%c in (red green blue) do echo Color: %%c
rem File wildcards (this is a glob, not a literal string):
for %%f in (*.txt) do echo Text file: %%f
for %%f in ("C:\logs\*.log") do (
echo %%~nxf is %%~zf bytes
)
The same ~ modifiers from Lesson 4 work: %%~nxf, %%~dpf, %%~zf, %%~tf, etc.
Mode 2: for /L — counting¶
rem for /L %%i in (start, step, end)
for /L %%i in (1,1,5) do echo %%i &rem 1 2 3 4 5
for /L %%i in (10,-2,0) do echo %%i &rem 10 8 6 4 2 0
for /L %%i in (0,1,3) do echo tick
The end value is included (unlike many languages).
Mode 3: for /D — directories¶
rem Immediate subdirectories of the current folder:
for /D %%d in (*) do echo Subfolder: %%d
for /D %%d in ("C:\Projects\*") do echo %%~nxd
Mode 4: for /R — recurse a tree¶
rem Every .log under C:\logs and below:
for /R "C:\logs" %%f in (*.log) do echo %%f
rem Every directory under the current one:
for /R %%d in (.) do echo DIR: %%d
for /R walks the whole subtree. Combine with if to filter. More in Advanced Lesson 1.
Mode 5: for /F — parse text¶
The most powerful and the most complex. It reads lines from a file, a string, or the output of a command, and splits each line into tokens.
rem Lines of a file:
for /F "usebackq delims=" %%L in ("names.txt") do echo LINE: %%L
rem Output of a command:
for /F "tokens=*" %%L in ('whoami') do echo I am %%L
rem Split on a delimiter, grab specific columns:
for /F "tokens=1,3 delims=," %%a in ("alice,30,london") do echo %%a lives in %%b
for /F gets its own lesson: Intermediate Lesson 3. For now, know it exists and that tokens=, delims=, skip=, usebackq are its options.
break and continue?¶
There is no break and no continue in batch for.
- To skip an iteration: wrap the body in
ifso nothing runs. - To stop early: there's no clean way. Set a flag and
if defined donearound the body, or restructure usinggotoout of the loop (you cannotgotoa label inside the sameforand keep looping, but you cangotoout).
set "found="
for %%f in (*.txt) do (
if not defined found (
findstr /m "TODO" "%%f" >nul && set "found=%%f"
)
)
if defined found echo First match: %found%
The counter bug (preview)¶
This does not work as written:
@echo off
set /a count=0
for %%f in (*.txt) do (
set /a count+=1
echo %count% REM <-- always prints 0
)
echo Total: %count% REM <-- this one is correct
%count% inside the block is frozen at parse time. Fix: setlocal enabledelayedexpansion and !count!. Full explanation in Intermediate Lesson 1.
Common mistakes¶
%iinstead of%%iin a script →%i was unexpected at this time.- Expecting
break/continue— they don't exist. - Reading
%var%set inside the loop — it's stale; you need delayed expansion. for %%f in (*.txt)when there are no matches — the loop body runs once with%%f= the literal*.txt. Guard withif exist *.txtor check%%~ff.for /Fon a file with nousebackqand a quoted path — withoutusebackq,"names.txt"is treated as a literal string to parse, not a filename. Useusebackqfor quoted filenames.- Spaces in the
(start,step,end)of/Lare tolerated but be consistent:(1,1,5).
Exercises¶
- Print the numbers 1 to 20, and separately the even numbers 2 to 20, using
for /L. - List every
.mdfile in the current folder with its size in bytes (%%~zf). - Print every immediate subfolder of
%USERPROFILE%usingfor /D. - Recursively count how many
.txtfiles are under the current folder. (You'll need the counter workaround or a>>to a temp file, or justdir /s /b *.txt | find /c /v ""— try both.) - Given the string
2026-09-07, usefor /F "tokens=1-3 delims=-"to printDay 07, Month 09, Year 2026. - Loop over
red green blue; skipgreenwith anif.
Recap¶
- Script loop variable is
%%i; prompt is%i. Single letter, case-sensitive. for(list/glob),for /L(counting, end inclusive),for /D(subdirs),for /R(recursive),for /F(parse text).~modifiers work on the loop variable:%%~nxf,%%~zf, ...- No
break, nocontinue— use flags andif. - Variables set inside a
( )block read stale without delayed expansion.
Next: Files & folders →