/commands/cmd/for-f-loop-parse-output
for /f in cmd: read a file line by line or capture a command's output
- tool
- Command Prompt (cmd)
- versions
- Windows 10, Windows 11, Windows Server 2016+
- os
- windows
for /f reads text line by line and splits each line into tokens. The source can be a file (in (file.txt)), a command (in ('command')) or a literal string (in ("text")). Options in quotes control parsing: tokens=1,2 picks fields, delims=, sets the separators (default: space and tab), skip=1 skips header lines. In a batch file the loop variable is written %%a; at the prompt it is %a.
for /f "skip=1 tokens=1,2 delims=," %%a in (data.csv) do echo %%a has %%b
for /f "delims=" %%l in ('git rev-parse --short HEAD') do set "COMMIT=%%l"Examples
> data.csv echo name,qty
>> data.csv echo apple,3
>> data.csv echo pear,5
for /f "skip=1 tokens=1,2 delims=," %%a in (data.csv) do echo %%a has %%b
for /f "tokens=2" %%w in ("alpha beta gamma") do echo second word: %%w
for /f "tokens=1,*" %%a in ("key rest of the line") do echo key=[%%a] rest=[%%b]
for /f "delims=" %%v in ('cmd /c echo captured output') do set "RESULT=%%v"
echo RESULT=%RESULT%Output
apple has 3 pear has 5 second word: beta key=[key] rest=[rest of the line] RESULT=captured output
Note the redirection written first (> data.csv echo apple,3): echo apple,3>> data.csv would be read as "redirect stream 3", and the 3 would be lost.
Options
| Option | Meaning |
|---|---|
| tokens=1,3 / tokens=2-4 / tokens=1,* | fields to assign; * puts the rest of the line in the next variable |
| delims=,; | separator characters; delims= with nothing keeps the whole line |
| skip=N | skip the first N lines |
| eol=# | lines starting with this character are ignored (default ;) |
| usebackq | backquotes run a command, double quotes mean a file name, so paths with spaces work |
With tokens=1,2, the first token goes to %%a, the second to %%b (the next letters). Empty lines are always skipped.
Paths with spaces and commands with quotes
for /f "usebackq delims=" %%l in ("C:\My Data\list.txt") do echo %%l
for /f "usebackq delims=" %%l in (`where "node.exe"`) do echo found %%lWithout usebackq, ("C:\My Data\list.txt") is a literal string, not a file.