Loop command: Parse the output of another command, line by line, optionally assigning parts of each line to variable parameters. You then have the option to perform another command against each variable parameter.
Syntax
FOR /F ["options"] %%parameter IN ('command_to_process') DO command
Key
options:
delims=xxx The delimiter character(s) default: a Space, TAB, comma, Equals or Semicolon.
skip=n A number of lines to skip at the beginning. Default = 0.
eol=; Character at the start of each line to indicate a comment
The default is a semicolon ;
tokens=n The numbered items to read from each line. Default = 1.
usebackq Use the alternate quoting style:
- Instead of double quotes use single quotes for 'Text string to process'
- Use double quotes for long file names in "filenameset".
- Use back quotes for `command_to_process`
command_to_process : The output of the 'command_to_process' is passed into the FOR parameter.
command : The command to carry out, including any parameters. This can be a single
command, or if you enclose it in (brackets), several commands, one per line.
%%parameter : A replaceable parameter:
in a batch file use %%G or on the command line %G
FOR /F processing of a command consists of reading the output from the command one line at a time and then breaking the line up into individual items of data or 'tokens'. The DO command is then executed with the parameter(s) set to the token(s) found.
Read the main FOR introduction page for a full description of assigning the replaceable %%parameter.
FOR parameters are used in all variations of the FOR command, it is a good idea to get up to speed with writing a basic FOR command before trying the more complex FOR / F variant.The FOR /F command is the answer to innumerable questions where you want to take the output of some command, store it in a variable (%%G) then do something with the result.
For example the PING command returns serveral lines including one like:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
To select that one line of output, you can search for the text "loss" (which is always present), then use the Tokens parameter to select the number of lost packets, here this is 0 but it will vary each time you run the command.
SET _cmd=ping -n 5 127.0.0.1
FOR /f "tokens=4 delims=(=" %%G IN ('%_cmd% ^|find "loss"') DO echo Result is [%%G]The tricky part is splitting up the line of interest into the right tokens, in this case we are splitting on the characters '=' and '('
those two characters split the line into 5 chunks of text and we pull out the fourth one with "tokens=4"By default, /F breaks up the command output at each blank space, and any blank lines are skipped.
You can override this default parsing behavior by specifying the "options" parameter. The options must be contained within "quotes"It is possible to use the syntax on this page to parse a text file with TYPE ('Type somefile.txt') but you will get much better performance using FOR /F File contents (somefile.txt) as that will save loading TYPE.EXE.
The precedence/priority of FOR command options is: usebackq > skip > delims > eol > tokens
The FOR command is quite flexible in how it extracts items from a text string (or command output).
So given a string like "Price 123 tax 27 postage 14" we can extract the numbers by breaking apart on the spaces,
or given a string like "Price~123~tax~27~postage~14" we can extract the numbers by breaking apart on the '~' character.
This is known as a delimiter character.This is similar to but separate from the delimiter characters accepted by the CMD command shell itself.
More than one delimiter can be specified, so a string like 'abcd+efg+hijk;lmno;pqr' can be broken up using "delims=;+".
for /f "tokens=1,2,3,4,5 delims=;+" %%G in ('type filename.txt') do echo %%G %%H %%K
Delimiters are discarded and do not form part of the variables, e.g. if you split up a string on the '~' character (using delims=~) then none of the resulting tokens will contain a '~' character.
If you only need to process one item at a time, use "delims="
This will place everything on the line into the first token. even if it contains spaces, e.g. a long filename.for /f "delims=" %%G in ('dir /b C:\demo\*.*') do echo %%G
delims should always be the last item in the options string:
"tokens=3 delims= "
rather than
"delims= tokens=3"
This is because the quotations around the options string do double duty as a terminator for the delims character(s), which is particularly important when that character is a space.TABs and Spaces
If you don’t specify delims it will default to:
"delims=<TAB><Space>"
If you specify a different delimiter, but still want to break on spaces/tabs then include a Space and/or TAB character in the delims= string. Some text editors will enter a TAB character as a series of spaces. If you need a TAB make sure you enter one, or copy this: ""When including a space character as a delimiter it must be last one in the delims= clause.
So, for a list of delimiters such as Semicolon,Equals,Space, this is valid: "delims=;= " but this is not valid: "delims=; ="When including a TAB character as a delimiter it can be placed anywhere in the delims= clause. Tabs are impossible to enter at the command line, so this can only be done within a batch file.
In addition to <TAB> and <SPACE> the following ASCII characters can be used as FOR delimiter characters:
Numbers: 0 1 2 3 4 5 6 7 8 9
Upper case letters: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Lower case letters: a b c d e f g h i j k l m n o p q r s t u v w x y z
ASCII characters: ☻ ☻ ♥ ♦ ♣ ♠ • ◘ ○しろまる ◙ ♂ ♀ ♪ ♫ ☼ ► ◄ ↕ !! ¶ § ▬ ↨ ↑ ↓ → ← ∟ ↔ ▲さんかく ▼
! # $ & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
Extended ASCII/Unicode characters: " " ‘ ’ „ ‚ « » ¶ ‹ › ¡ ¿ Ƒ · • – — i œ ÿ ž ¢ £ € ₱ ¤ \ ¦ § © ® ° ± 2 3 ́ μ 1⁄4 1⁄2 3⁄4 Æ æ ×ばつ ÷ π ≠ ⋮ TM ̃░ ▒ ▓ │ ┫ ─ ┌ ┐ ┘ └ √ ∑ ∞ ≡Notice that the A-Z characters are case sensitive, to split a string on q and Q, list both in the delims= clause.
Other unicode characters may also work for this, even though most unicode characters do not display properly in the CMD shell.
Characters that do NOT work as a delimiter without being escaped: % " ̃
Using a double quote (") as delimiter is a common request. If a double quote (") needs to be used as a delimiter, then it needs to be prefixed with a escape (^) , otherwise it will be interpreted as the end of the parameters/delims string.
This approach involves:
- Leaving out the "double quotes" enclosing the options string.
- Prefix with a escape (^) all punctuation characters in tokens, delims and eol including the (=) character.
for /f tokens^=1^,2^,3^ delims^=^" %%G in (filename.txt) do echo %%G %%H %%I
It is hard to recommend this technique because it is not very readable, so another way to approach 'problem' characters is to temporarily replace them with an alternative character that is easier to parse.Consecutive Delimiters
Consecutive delimiters will be treated as one, even if they are different characters.
This means that if any data values are missing between delimiters the subsequent items in that line will be assigned a different token, e.g.Bread,Organic,1ドル.49
Cheese,,2ドル.99
In the first line the price will be assigned to the third token, but for the second line, the price will be assigned to the second token.
A common workaround for this issue is to pre-process the input data adding a placeholder character between any consecutive delimiters. e.g. replace ',,' with ',~,'
Given a string like "Price~123~tax~27~postage~14"
If we set the delimiter character to "~" then everything else in the string will be split up into tokens, in this case six tokens automatically numbered 1 through 6. (1='Price'... 6='14')tokens=2,4,6 Will cause the second, fourth and sixth items on each line to be processed (3 Tokens).
tokens=2-6 Will cause the second, third, fourth, fifth and sixth items on each line to be processed (5 Tokens).
tokens=* Will cause all items on each line to be processed as a single string Token.
tokens=3* Will process the third item as one string token and then all subsequent text as a second string Token.
This can also be written as tokens=3,*
If the last character in the tokens= string is an asterisk '*', then one additional parameter is added for all the remaining text on the line.If an asterix is used in the tokens= string then it must be the last character in the string.
The parameter added by the asterix is based on the whole tokens= string and not on the number preceding the asterix, so if you select tokens 1,2,* the asterisk will represent the third and all subsequent items, and if you select tokens=19,2,1,* then the asterisk will represent the 20th and all subsequent items.
Each token specified will cause a corresponding parameter letter to be allocated. The letters used for tokens are case sensitive.
The following ASCII characters can be used as FOR tokens:
ASCII 63 - 93 inclusive, 31 tokens: ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ]
ASCII 95-123 inclusive, 29 tokens: _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z {
(there are a few other characters that can be used, but require escaping)A single FOR /F command can never parse more than 31 tokens, to use more requires a workaround with multiple FOR commands.
The tokens selected do not have to be listed in numeric order, though it is usually more readable to do so. The numbers selected in tokens= are automatically sorted, so for example tokens=5,7,1-3 and tokens=1,2,3,5,7 both produce the same result.
Matching the same token more than once (tokens=1,2,1) can give unpredictable results. Token variables can of course be used multiple times: Echo %%G %%H %%G
FOR tokens variables (or parameter names) are global, so in complex scripts which call one FOR statement from within another FOR statement you can refer to both sets of parameters.Bugs: When using tokens=* (just an asterisk, and no other tokens) against a string which contains one or more delimiter characters and no other text, then the commands will be executed despite no text matching the token having been found, an empty parameter is generated. More complex patterns like tokens=1,* do not behave this way.
This option is useful when dealing with a command that already contains one or more straight quotes.
The backquote character ` is just below the ESC key on most keyboards. See the FOR /F page for other effects of usebackq.Usebackq can be abbreviated to useback (undocumented.)
SKIP will skip processing a number of lines from the beginning of the file.
SKIP includes empty lines, but after the SKIP is complete, FOR /F ignores (does not iterate) empty lines. Some commands, in particular WMIC will append extra carriage returns to otherwise blank lines at the end of their output. To skip these, add a goto command to break out of the FOR loop.
The default end-of-line character is a semicolon ';' when the FOR command reads a text file (or even a character string), any line that STARTS with the eol character will be ignored. In other words it is treated as a comment.
Use eol=X to change the eol character to X.You may wish to turn this feature off so that every line of your data file is processed, in theory "eol=" should turn this feature off, but in practice this fails to work correctly, it will set eol to whatever the next character is – often the quote or space character. One workaround is to set eol to some unusual character that you don’t expect to ever encounter in the data file e.g. "eol=€" or "eol=¬". Another method is to escape every delimiter For /f tokens^=*^ delims^=^ eol^= %%a in (file.txt) do... (see forum for a discussion of this).
If you are using a delims then you can use the syntax "eol= delims= " which will set the eol so that nothing is treated as a comment.
The command_to_process can be almost any internal or external command, but there are a few commands that have no effect when they are called through FOR /F: SHIFT, SETLOCAL, ENDLOCAL and CALL:Subroutine.
To be clear these can be used as part of command, but not command_to_processIf the command_to_process is a long filename, you will need to surround it in double quotes, similarly any parameters with spaces need to be double quoted. In addition to that the entire command_to_process needs to be enclosed in another set of double quotes like so:
FOR /f %%G in ('""C:\Program Files\some Program.exe" "a string" "second""') do...
This is because the FOR command will start the program in a new sub-shell which removes the outer set of double quotes.
If any of the strings contain multiple consecutive delimiters (typically spaces) then you may need to escape them otherwise they will be merged into a single delimiter/space. e.g. for 3 consecutive spaces: "before ^ ^ after"
Escape any Special Characters in command_to_process.
If any of the strings contain characters which need to be escaped such as an Ampersand, Caret or a Pipe, (e.g. a folder path such as
"C:\Demo & Folder\") then you have a couple of options:Escape each special character with ^
FOR /f /"tokens=* delims=" %%G in ('""C:\Demo ^& Folder\demo.exe" "C:\Demo ^& Folder\data.csv""') do echo %%G
or add an escape to the outer set of quotes:
FOR /f "tokens=* delims=" %%G in ('^""C:\Demo & Folder\demo.exe" "C:\Demo & Folder\data.csv"^"') do echo %%G
If you are passing the filenames using variables, again you can Escape each special character with ^:
Set _exe="C:\Demo ^& Folder\demo.exe"
Set _datafile="C:\Demo ^& Folder\data.csv"FOR /f "tokens=* delims=" %%G in ('"%_exe% %_datafile%"') do echo %%G
or add an escape to the outer set of quotes:
Set _exe="C:\Demo & Folder\demo.exe"
Set _datafile="C:\Demo & Folder\data.csv"FOR /f "tokens=* delims=" %%G in ('^"%_exe% %_datafile%^"') do echo %%G
Often the command will manipulate the data returned by the tokens/parameters in some way, but this is not required, the command can be almost any internal or external command.
A common pattern is to set a variable = some token output to make it available for later processing/display. When doing this be sure to read the section Using variables within a FOR loop on the main FOR page.
When using the FOR command in a batch file always use SETLOCAL at the start to localise all variables. Alternatively you can explicitly clear the variable(s) to remove any existing value, just before running the FOR loop.
FOR does not, by itself, set or clear an Errorlevel, leaving that to the command being called.
FOR is an internal command.
Select just the version number from the output of VER:
@Echo off
For /f "tokens=3,*" %%G in ('ver') do echo The version is [%%HHow would you modify this to remove the square brackets from the output? (hint you will need a delims=).
To ECHO from the command line, the name of every environment variable.
FOR /F "delims==" %G IN ('SET') DO @Echo %G
The same command with usebackq:
FOR /F "usebackq delims==" %G IN (`SET`) DO @Echo %G
To put the Windows Version into an environment variable
@Echo off
::parse the VER command
FOR /F "tokens=4*" %%G IN ('ver') DO SET _version=%%G
:: show the result
echo %_version%
List all the text files in a folder:
FOR /F "tokens=*" %%G IN ('dir /b C:\docs\*.txt') DO echo %%G
The "tokens=*" has been added to match all parts of any long filenames returned by the DIR command.
List all the text files in a folder, including the full path:
FOR /F "tokens=*" %%G IN ('dir /b /s ^"c:\program files\*.txt^"') DO echo %%G
We use DIR /S (even if the folder has no subfolders) to make DIR return the full path to each file.
In the example above the long filename has to be surrounded in "quotes" and those quotes have to be escaped using ^
Although the above is a trivial example, being able to set a variable equal to each long filename in turn allows much more complex processing to be done.
More examples can be found on the Syntax / Batch Files pages and the other FOR pages below.
"History never repeats itself, Mankind always does" ~ Voltaire
FOR - Summary of FOR Loop commands.
FOR - Loop through a set of files in one folder, or a list of folders.
FOR /R - Loop through files (recurse subfolders).
FOR /D - Loop through several folders.
FOR /L - Loop through a range of numbers.
FOR /F - Loop through items in a text file.
SETLOCAL - Control the visibility of variables inside a FOR loop.
FORFILES - Batch process multiple files.
GOTO - Direct a batch program to jump to a labelled line.
IF - Conditionally perform a command.
Equivalent PowerShell: ForEach-Object - Loop for each object in the pipeline.
Equivalent bash command (Linux): for - Expand words, and execute commands