Programming Field

For - DOS/Command Prompt Reference

Enumerates files in the (current) directory and executes commands for each files. So-called ‘for statement’.

[Windows NT series] [Extensions] Also used for parsing texts with specifying appropriate options.

Syntax

for %variable in (<pattern>) do <command-line>
for /D %variable in (<pattern>) do <command-line>
for /R [[<drive-letter>:]<path>] %variable in (<pattern>) do <command-line>
for /L %variable in (<start>,<step>,<end>) do <command-line>
for /F ["<options>"] %variable in (<pattern>) do <command-line>

In batch files, you must write two ‘%’ characters like ‘%%variable’. If you use single ‘%’ character, it is treated as the environment variable character ‘%’, and is replaced with the variable's value (or an empty text).

* It is not limited to For that passing ‘%’ character to commands or programs in batch file requires to write ‘%%’. See also ‘%’ page.

Options

%variable
Defines the variable. You must specify one alphanumeric character to ‘variable’. This variable can be used in the <command-line>, replaced with the enumerating file name. Note that the variable character is case sensitive.
<pattern>
Specifies the file name to search. Normally uses wildcards to enumerate multiple files.
You can also specify multiple patterns with space-separated. (e.g. ‘(*.txt *.log)’)
[Windows NT series] [Extensions] With /F option the syntax of <pattern> changes. Please see ‘Parsing texts with Extension syntax’.
<command-line>
Specifies the command line to execute for each values. You can specify not only the command name, but also command parameters. This command line is executed by the command interpreter, meaning that you can use internal commands such as Echo.
By including ‘%variable’ you can specify enumerating values to the command.
[Windows NT series] To suppress echo back of commands, use ‘@’ on the head of commands. To specify multiple commands, enclose them with ‘( )’. When using ‘( )’, be careful for the timing of environment variable expansion. (Please see ‘( )’, Setlocal, and ‘!’ pages.)
/D
[Windows NT series] [Extensions] Enumerates directories instead of files.
/R [[<drive-letter>:]<path>]
[Windows NT series] [Extensions] Searches files from the directory, specified in ‘[<drive-letter>:]<path>’, and its subdirectories, and executes the command for each files which matches the pattern <pattern>. (If omitting ‘[<drive-letter>:]<path>’, the current directory is used.) When specifying ‘.’ (one dot) to <pattern>, directories and subdirectories (i.e. all ‘.’ directory) are enumerated.
/L ... (<start>,<step>,<end>)
[Windows NT series] [Extensions] Enumerates numbers between <start> and <end> (%variable will be expanded to its number. Similar to ‘for statement’ for common programming languages.) The enumerated number value starts with <start>, increases the value <step>, and ends when the enumerated value is larger than <end>. When the value <step> is negative, the enumerated value starts with <start>, decreases the value ‘-<step>’, and ends when the enumerated value is smaller than <end>. If ‘<start><end>’ (or ‘<start><end>’ when <step> < 0), the enumeration is not performed.
/F ["<options>"]
[Windows NT series] [Extensions] Reads and parses each lines of the data specified in <pattern>, and executes <command-line> for each parsed string. %variable will contain the parsed string. Parsing options can be specified in ‘"<options>"’ (see details).
<pattern> will be the file name (multiple files by separating with spaces or semicolons), the string value (surround with " "), the command line (surround entire command line with ' '), and the file content, the string value itself, or the output (to the STDOUT) of the command line respectively are used for the input. If <options> includes ‘usebackq’, the string value must be enclosed with ' ', and the command line must be enclosed with ` ` (this behavior enables to use " " when specifying the file name).
* When specifying the command line to <pattern>, ‘^’ (escaping) is necessary to use pipe and redirection. Please be careful that using multiple commands surrounding with ‘( )’ may cause unexpected behavior.

Details

About ‘For’

Usage of For

By default, the For command enumerates files and executes the command on each files. For example, executing For with the pattern ‘*.*’ in some directory can execute same command on every file in the directory. Note that if the command being executed makes a file matching the specified pattern, that file will also be enumerated.

‘in’ and ‘do’ in the syntax cannot be omitted; otherwise the syntax error will occur.

This command does not enumerate directories (unless using ‘/D’ option). Andmore, files with hidden or system-file attribute(s) aren't enumerated.

[Windows NT series] [Extensions] To enumerate files with hidden or system-file attribute(s), use ‘/F’ option and Dir command (see Sample 8).

[Windows NT series] [Extensions] If Command Extensions syntax is enabled (enabled by default), ‘~’ character can be used as an extension for variable expansion as well as batch file parameters such as ‘%1’ and ‘%2’ (e.g. ‘%~dpA’). For detailed syntax, please see ‘%’.

Parsing texts with Extension syntax

[Windows NT series] [Extensions] For can be used for parsing text data by using ‘/F’ option. The options that can be specified in ‘"<options>"’ are as followings:

eol=c Specifies one end-of-line character. The string including and after the character c will be ignored for parsing. If not specified, the string just before return character (i.e. entire line) is parsed.
skip=n Skips (ignores) first n line(s) of input data. n is the line count value to skip.
delims=delimiters Specifies the delimiters. The characters (one or more characters) in delimiters will be used as delimiters (note that each one character will be used; string block of 2 or more characters cannot be specified as delimiters). You can include a space character to delimiters, but the space must be specified as a last character, and ‘delims’ option must be the last specified option. If ‘delims’ is not specified, space and tab characters are used as delimiters. If delimiters’ is empty (i.e. specified as ‘"delims="’), the data will not be separated, and the entire line will be stored to %variable.
tokens=token[,token...] Specifies the token number(s) of parsed data to use as %variable. By using this option, the additional variables can be used, such like ‘%2’ ‘%3’ for %variable being ‘%1’, or ‘%j’ ‘%k’ for %variable being ‘%i’. token will be the number, the range (m-n), or ‘*’. The number value is one-based index (nth) of separated data. The range is ‘m-n’ value meaning using from mth to nth values as %variable and additional variables. By using ‘*’ such like ‘2*’ or ‘2,*’ (same meaning), the rest data (which is not picked by token) will be stored to the variable without separating.
usebackq Switches the data of <pattern> from file-name "string" 'command-line' to "file-name" 'string' `command-line` (in this case the file name can be without surrounding with " "). If you want to specify the file name including spaces or ‘( )’ characters, you must use this option and enclose the name with ‘" "’.

For detailed usage, please see Samples (Sample 5 or later).

* The delimiters to use are different for the empty delimiters (i.e. "delims=") and no ‘delims’ option. To use the entire line (without separating input data with delimiters), explicit ‘delims=’ is necessary. (Note that ‘delims=’ must be the last option to prevent a space character from being treated as a delimiter.)
* You can only specify one ‘eol=’ (one character). If you want to use multiple end-of-line characters, consider using multiple For. To drop lines beginning with specific character, use Findstr. (For sample, see ‘Sample 10’.)

Note that in case specifying the string for <pattern>, return characters in the string will be treated as spaces (and treated as delimiters when ‘delims=’ includes spaces). Therefore, to specify multiline string, you need to use ‘^’ character. In this case, using ‘usebackq’ is necessary; otherwise ‘^’ character is surrounded by ‘" "’ causing ‘^’ treated as a regular character (i.e. no effect).

for /f "usebackq tokens=1,2 delims=:" %A in ('C1:Flower^

C2:Bird^

C3:Wind^

C4:Moon') do echo The value for key '%A' is '%B'.

* Two return characters are necessary just after ‘^’. For more information, please see ‘^’ character page.

In case of specifying a command line to <pattern> and including single quotations ‘'’ and/or carets ‘`’ to the command line, please note the following:

  • The ‘')’ string (a single quotation and a closing parentheses; when no ‘usebackq’ is used) or the ‘`)’ string (a caret and a closing parentheses; when ‘usebackq’ is used) are treated as the command line terminators. Therefore, if the command line contains ‘')’ and/or ‘`)’, ‘^’ is necessary; you need to write such as ‘'^)’ and ‘`^)’.
  • The ‘'’ and ‘`’ symbols other than the above are not treated as closing symbols, so ‘\’ and ‘^’ are not necessary just before ‘'’ and ‘`’ symbols, and you don't need to write such as ‘''’ and ‘``’. Just one ‘'’ or ‘`’ character will be treated as is as a part of the command line.
  • You can use For as a command line, but when using /F on the command line inside For, and using ‘( )’ on the <pattern> inside For, you need to use multiple ‘^’ in the form like ‘^^^)’ (to pass ‘^’ to the grandchild command).
  • The only content outputted to standard output (STDOUT) will be parsed; the content outputted to standard error (STDERR) will not be handled (usually printed to the screen). To parse contents of STDERR, or to suppress the contents, use ‘>’ redirection for the command. But inside ' ' ‘^’ escaping is necessary for ‘>’ (like ‘2^>&1’ or ‘2^>NUL’).

Based on those points, triple For commands can be used (nested).

for /f "tokens=1,2 delims=?" %A in ('for /f "delims=" %X in ('for /f "delims=" %Y in ('dir /b'^^^) do @echo %~fY'^) do @echo %~X?%~zX') do @echo %~nxA, %B

Samples

Sample 1

for %d in (*.dll) do regsvr32.exe /u "%d"

Executes regsvr32.exe for each DLL files in the current directory, and unregisters COM DLL.

Sample 2 (Batch file)

@echo off
for %%f in (*.*) do echo %%f

Displays all files (excluding directories and hidden/system files) in the current directory.

Sample 3

for /L %n in (8,-3,1) do @echo %n

[Windows NT series] [Extensions] Prints ‘8’, ‘5’, and ‘2’.

Sample 4

for /L %n in (1,1,%NUMBER_OF_PROCESSORS%) do hoge.exe %n

[Windows NT series] [Extensions] Executes ‘hoge.exe’ as many times as the count of (logical) processors, and passes the index to the program. (‘NUMBER_OF_PROCESSORS’ is defined by OS.)

Sample 5

for /F "tokens=1,2,*" %1 in ("This is a pen.") do @echo "%1" "%2" "%3"

[Windows NT series] [Extensions] Parses the text by using ‘/F’. The variables not only ‘%1’ but ‘%2’ and ‘%3’ will be defined by using ‘tokens’ options. (By ‘*’ specifier, ‘%3’ will contain the all remaining tokens not contained in ‘%1’ and ‘%2’.) This command will display ‘"This" "is" "a pen."’.

Sample 6

for /F "tokens=2,3 delims=-" %p in ("%DATE%") do @echo %p%q

[Windows NT series] [Extensions] Extracts the month and day from the current date and outputs those with concatenation (in case the system date format is ‘yyyy-mm-dd’).

Sample 7

for /F "usebackq delims=" %t in ("D:\My Files\hoge.txt") do @foo.exe "%t"

[Windows NT series] [Extensions] Executes ‘foo.exe’ for each lines in ‘D:\My Files\hoge.txt’ as a parameter. The file name contains a space character, so ‘usebackq’ option is necessary. Since the option ends with ‘delims=’, %t will contain entire one line data.

Sample 8

for /F "delims=" %F in ('dir /A /B') do @echo %~fF

[Windows NT series] [Extensions] Outputs full paths of directories and files in the current directory. All files and directories, including hidden and system files (directories), are enumerated by Dir command with ‘/A’ option, and the file names are outputted one by line by ‘/B’ option, so For's ‘%F’ variable will contain those file names. Note that ‘%~fF’ represents the full path of the file (see ‘%’).

* If you want to exclude directories (but include hidden and system files), use the command ‘dir /A:-D /B’.

Sample 9 (Batch file)

for /F "tokens=1,2 delims=," %%p in ('tasklist /FO CSV /NH') do (
    if /i "%%~p"=="explorer.exe" echo %%~q: %%~p
)

[Windows NT series] [Extensions] Divides the output of ‘tasklist /FO CSV /NH’ (the executing process list with CSV format) with ‘,’, picks the line where the first token (the process name in this case) equals ‘explorer.exe’, and prints the first and the second (the process ID in this case) tokens. Note that ‘%~p’ (using ~) will eliminate the double quotations ‘" "’.

* This sample uses double ‘%’s due to the batch file.

Sample 10

for /F "tokens=1,2 delims=?" %a in ('^(for /R %x in ^(*.cpp^) do echo %~tx?%x?^) ^| findstr /r "^200[0-4]" ^| sort') do @echo %b : %a

[Windows NT series] [Extensions] Searches ‘*.cpp’ files in the current directory and its subdirectories, picks the files where the update date is between the year of 2000 and 2004, and displays them from oldest to newest. To get the desired result, this sample uses For and the pipe in the ‘for /F’ (also uses ‘^’ character to be interpreted correctly).

First, this executes the following command inside the parentheses just after ‘in’ of the first For.

(for /R %x in (*.cpp) do echo %~tx?%x?) | findstr /r "^200[0-4]" | sort

On this command For will search ‘*.cpp’ files in the current directory and its subdirectories, and prints those update dates (‘%~tx’) and file names with the separator ‘?’ by using Echo command. This For command will print as follows:

2013-06-30?G:\My Sources\Project1\hello.cpp?
2004-02-29?G:\My Sources\ProjectArchive\Hoge1\file1.cpp?
2003-01-30?G:\My Sources\ProjectArchive\Hoge1\file2.cpp?
2012-10-05?G:\My Sources\Temp\temp.cpp?

* ‘( )’ is necessary outside For to pass the entire output (result) by For to the next command.

Next, this uses Findstr command to pick the string beginning with one of 2000, 2001, 2002, 2003, or 2004 (this uses a regular expression ‘^200[0-4]’ available in Findstr). This will result as follows:

2004-02-29?G:\My Sources\ProjectArchive\Hoge1\file1.cpp?
2003-01-30?G:\My Sources\ProjectArchive\Hoge1\file2.cpp?

And, Sort command sorts the text in ascending order, resulting as follows:

2003-01-30?G:\My Sources\ProjectArchive\Hoge1\file2.cpp?
2004-02-29?G:\My Sources\ProjectArchive\Hoge1\file1.cpp?

Finally, this command lets outer For with ‘/F’ option interpret the result above. The command line specified to the outer For includes the pipe and the parentheses, so ‘^’s are necessary for each special characters to avoid that For interprets them.

The final result will be as follows:

G:\My Sources\ProjectArchive\Hoge1\file2.cpp : 2003-01-30
G:\My Sources\ProjectArchive\Hoge1\file1.cpp : 2004-02-29

Note that ‘%b’ variable of outer For will contain the valid file name (as a result), so you can get the name without directory name by using ‘%~nxb’ and the file size by using ‘%~zb’.

* In case of writing For inside For in the batch file, you do not need to write the % variable of inner For (‘%x’ for the above sample) as ‘%%%%x’; you only write ‘%%x’ just like the normal usage of variables in the batch file.

Sample 11 (Batch file)

@echo off
setlocal enabledelayedexpansion
set TEMPLATE_FILE=D:\Data\Template\hoge.xml
set OUT_FILE=D:\MyData\bar.xml
set MY_VERSION=123

type NUL > "%OUT_FILE%"
for /F "usebackq delims=" %%t in ("%TEMPLATE_FILE%") do (
    set TEMP_LINE=%%t
    set TEMP_LINE=!TEMP_LINE:[version]=%MY_VERSION%!
    echo !TEMP_LINE!>> "%OUT_FILE%"
)

[Windows NT series] [Extensions] Creates the file ‘D:\MyData\bar.xml’ based on the template file ‘D:\Data\Template\hoge.xml’. During the creation, if ‘D:\Data\Template\hoge.xml’ contains ‘[version]’, it is replaced with the value of the variable ‘MY_VERSION’ (‘123’ in this case). Clears the output file content in line 8 and writes and appends the converted data in line 12.

In this sample the line data is stored to the temporal variable (to replace ‘[version]’ string), rewritten by using extended expansion of ‘%’, and written to the file. Note that the delayed expansion of environment variables (the effect of ‘!’) is used to treat the variable in For command line. (Using ‘%’ instead of ‘!’ will result in unexpected behavior.)

* In this sample ‘hoge.xml’ must be encoded with the current codepage (ANSI for 437), and if the file is UTF-8, ‘bar.xml’ may be garbled. Please see Chcp command's sample for using UTF-8 format.

See also