Purpose:Repeat a command for several values of a variable

 

Format:File and string mode

FOR [range...] [/I"text"] [/A:[[-|+]rhsadecijopt /D /F ["options"] /H /Nj /O:[-]acdeginorstuz /R [path]  [/T"delimiters"] /W ] %var IN ([@]set) DO command | (command ... [LEAVEFOR] )

 

Counted mode

FOR /L %var IN (start, step, end) DO command | (command ... [LEAVEFOR] )

 

optionsParsing options for a "file parsing" FOR.
rangeOne or more range specifications
path The starting directory for a "recursive" FOR.
%var The variable to be used in the command ("FOR variable").
set A set of values for the variable.
start The starting value for a "counted" FOR.
step The increment value for a "counted" FOR.
end The limit value for a "counted" FOR.
commandA command or group of commands to be executed for each value of the variable.

 

/A: (Attribute select)

/N (defaults)

/D(irectories only)

/O:... (Order)

/F(ile parsing)

/R(ecursive)

/H(ide dots)

/T (delimiter list)

/I description range

/W(ildcards)

/L (counted loop)

 

 

File Selection

 

Supports attribute switches, extended wildcards, ranges, multiple file names, and include lists.

 

Ranges must appear immediately after the FOR keyword after alias expansions (if any), and only affect the selection of files specified using wildcards.

 

Use wildcards with caution on LFN volumes; see LFN File Searches for details.

 

Usage:

 

FOR begins by creating a set. It then executes a command for every member of set. The command can be an internal command, an alias, an external command, or a batch file. The members of set can be a list of file names, text strings, a group of numeric values, or text read from a list of files.

 

When set is made up of text or several separate file names (not an include list), the elements must be separated by spaces, tabs, or commas.

 

FOR includes a large number of options, some of which duplicate functions available in other internal commands. It also supports additional conventions not found in our other commands, included for compatibility with CMD.

 

The first three sections below (Working with Files, Working with Text, and Retrieving Text from Files) describe the FOR command and the enhancements to it which are included in TCC. The sections on Parsing Text from Files and Counted FOR Loops describe features added for compatibility with CMD. The sections Directory Recursion and Output Redirection warn of special considerations. The section entitled Other Notes contains information you may need if you use any aspect of the FOR command extensively.

 

FOR sets two internal variables:

 

%_for_filesThe number of files processed
%_for_errorsThe number of errors

 

If the Duplicate CMD Bugs configuration option is set, TCC will emulate undocumented CMD behavior when FOR set arguments are split across multiple lines. For example:

 

for %a in (

one

two

three

) do (

echo %a

)

 

Working with Files

 

Normally, set is a list of files specified with wildcards. For example, if you use this line in a batch file:

 

for %x in (*.txt) list %x

 

Then LIST will be executed once for each file in the current directory with the extension .TXT. The FOR variable %x is set equal to each of the file names in turn, then the LIST command is executed for each file. (You could do the same thing more easily with a simple LIST *.TXT. We used FOR here so you could get a feel for how it operates, using a simple example. Many of the examples in this section are constructed in the same way.)

 

Set can include multiple files and include lists, like this:

 

for %x in (d:\*.txt;*.doc;*.asc e:\test\*.txt;*.doc) type %x

 

FOR supports wildcards and extended wildcards, as well as extended parent directory names, e.g., ...\*.txt to process all of the .TXT files that are contained in the directory 2 levels above the current directory.

 

By default those members of set that include wildcards match only files, not directories.

 

When you use FOR on an LFN drive, you must quote any file names within set which contain white space or special characters. The same restriction may apply to names returned in the FOR variable, if you pass them to TCC internal commands, or other commands which require quoting filenames with white space. FOR does not quote returned names automatically, even if you included quotes in set.

 

If set includes filenames, the file list can be further refined by using date, time, size, description and file exclusion ranges. The range or ranges must be placed immediately after the word FOR. Ranges affect only those members of set which contain wildcards. For example, the FOR below will process all of the *.TXT files that were created or updated on December 4, 2018, and of the file ABC.LST  regardless of its timestamp:

 

for /[d12-4-2018,+0] %x in (*.txt abc.lst) ...

 

If command is an internal command that supports ranges, an independent range can also be used in command itself.

 

You can also refine the list by limiting it with the /A: option to select only files that have specific attributes.

 

When you use wildcards to specify set, FOR scans the directory and finds each file which matches the wildcard name(s) you specified. If, during the processing of the FOR command, you create a new file that could be included in set, it may or may not appear in a some later iteration of the same FOR command. Whether or not the new file appears depends on its physical location in the directory structure. For example, if you use FOR to execute a command for all .TXT files, and the command also creates one or more new .TXT files, those new files may or may not be processed during the current FOR command, depending on where they are placed in the physical structure of the directory. This is a Windows constraint over which TCC has no control. Therefore, in order to achieve consistent results you should construct FOR commands which do not create files that could become part of set for the current command.

 

Working with Text

 

Set can also be made up of text instead of file names. For example, to create three files named file1, file2, and file3, each containing a blank line:

 

for %suffix in (1 2 3) echo. > file%suffix

 

You can also use the names of environment variables as the text. This example displays the name and content of several variables from the environment (see the general discussion of the Environment for details on the use of square brackets when expanding environment variables):

 

for %var in (path prompt comspec) echo %var=%[%var]

 

Retrieving Text from Files

 

If the name of a file in set is prefixed with @ ("at" sign), it is considered as an @file list. FOR extracts each line from the file and places it in the FOR variable.

 

Warning: if the line contains characters which are syntactically significant for TCC, for example, one of the characters <"[]|>, it may have undesirable effects. You may use the /X option of SETDOS to mitigate them.

 

If you use @CON as the filename, FOR will read from standard input (typically a redirected input file) or from a pipe. If you use @CLIP: (or @CLIP0: - @CLIP9:) as the filename, FOR will read any text available from the Windows clipboard. See Redirection and Piping for more information on these features.

 

See @file list for additional details.

 

Parsing Text from Files

 

Another method of working with text from files is to have FOR parse each line of each file for you. To begin a file-parsing FOR, you must use the /F option and include one or more file names in set. When you use this form of FOR, the variable name must be a single letter, for example, %a.

 

This method of parsing, included for compatibility with CMD, can be cumbersome and inflexible. For a more powerful method, use FOR with @filename as the set to retrieve each line from the file, as described in the previous section, and use variable functions like @FIELD, @INSTR, @LEFT, @RIGHT, and @WORD to parse the line (see Variable Functions for information on variable functions).

 

By default, FOR will extract the first word or token from each line and return it in the variable. For example, to display the first word on each line in the file FLIST.TXT:

 

for /f %a in (flist.txt) echo %a

 

You can control the way FOR /F parses each line by specifying one or more parsing options in a quoted string immediately after the /F. The available options are:

 

skip=n:  FOR /F will skip n lines at the beginning of each file before parsing the remainder of the file.

 

tokens=n, m, ...: By default, FOR /F returns just the first word or token from each parsed line in the variable you named. You can have it return more than one token in the variable, or return tokens in several variables, with this option.

 

This option is followed by a list of numbers separated by commas. The first number tells FOR /F which token to return in the first variable, the second number tells it which to return in the second variable, etc. The variables follow each other alphabetically starting with the variable you name on the FOR command line. This example returns the first word of each line in TEST.TXT in %d, the second in %e, and the third in %f:

 

for /f "tokens=1,2,3" %d in (test.txt) ...

 

You can also indicate a range of tokens by separating the numbers with a hyphen -.

 

eol=c: If FOR /F finds the character c in the line, it will assume that the character and any text following it are part of a comment and ignore the rest of the line.

 

delims=xxx..: By default, FOR /F sees spaces, tabs and commas as word or token delimiters. This option replaces those delimiters with all of the characters following the equal sign to the end of the string. This option must therefore be the last one used in the quoted options string.

 

usebackq : Duplicates the awkward CMD syntax. A back quoted string is executed as a command; a single quoted string is a literal string; and double quotes quote filenames in the file set. We don't recommend usebackq for batch files written for TCC, as TCC has much more elegant ways of doing the same things.

 

You can also use FOR /F to parse a single string instead of each line of a file by using the string, in quotes, as set. For example, this command will assign variable A to the string this, B to is, etc., then display this:

 

for /f "tokens=1,2,3,4" %a in ("this is a test") echo %a

 

"Counted" FOR Loop

 

The "counted FOR" loop is included for compatibility with CMD. In most cases, you will find the DO command more useful for performing counted loops.

 

In a counted FOR command, the set is made up of numeric values instead of text or file names. To begin a counted FOR command, you must use the /L option and then include three values, separated by commas, in set. These are the start, step, and end values. During the first iteration of the FOR loop, the variable is set equal to the start value. Before each iteration, the variable is increased by the step value. The loop ends when the variable exceeds the end value. This example will print the numbers from 1 to 10:

 

for /l %val in (1,1,10) echo %val

 

This example will print the odd numbers from 1 to 10 (1, 3, 5, 7, and 9):

 

for /l %val in (1,2,10) echo %val

 

The step value can be negative. If it is, the loop will end when the variable is less than the end value.

 

Numeric input may be entered in either decimal format (a sequence of 0-9 digits) or in hexadecimal format ("0x" followed by a sequence of 0-F hex digits).

 

WARNING! You must not have white space between start and the subsequent comma, nor between step and its subsequent comma. White space after the comma is accepted.

 

Directory Recursion

 

By default, FOR works only with files in the current directory or a specified directory. Option switch /R specifies that the search should  recursively process subdirectories. If you specify a directory name immediately after /R, FOR will start in that directory and then search each of its subdirectories. If no directory is specified after the /R, the search starts in the current default directory. If you do specify a directory, and its name includes any special characters, it must be enclosed in double quotes. For example, it must be quoted if it is specified with the aid of an environment variable, e.g., %windir\command.

 

There are two differences in the invocation of command caused by directory recursion:

 

The loop control variable contains the full name of the matching file

command is executed with the default directory set to the directory in which the file was found

 

This example processes all .TXT files in the current directory and its subdirectories:

 

for /r %x in (*.txt) ...

 

This example works with all of the .BAK files on drive D:

 

for /r d:\ %x in (*.bak) ...

 

Output Redirection

 

The default output redirection (i.e., for ... > filename) creates a new output file in each iteration. If filename does not include an absolute file path, it will be created relative to the then current default directory. If you use directory recursion, this path will change for each directory processed. The simplest way to force a single target file is to enclose the whole command in parentheses, e.g.,:

 

(for %x in (set) command) > filename

 

Other Notes

 

You can use either % or %% in front of the variable name (var) in the command. Either form will work, whether the FOR command is typed from the command line or is part of an alias or batch file. (CMD which requires a single % if FOR is used at the command line, but requires %% if FOR is used in a batch file.) Note that you must have at least one % sign present.

The variable name can be up to 80 characters long.

If the FOR command is an alias, e.g., alias for=*for /h, range specifications will be ignored.

The word DO is unnecessary but accepted. Do not confuse it with the completely unrelated DO command.

If the name of the FOR variable var is a single character, for compatibility with CMD, it is created in the environment in a special way that does not overwrite an existing environment variable with the same name. Wherever command contains the % sign immediately followed by the character which is the name of the FOR variable, it is replaced by its value, regardless of any characters following it. For example, the following command tries to add a: and b: to the end of PATH, but will not work as intended:

 

for %p in (a: b:) path %path;%p

path

b:ath;b:

 

The %p in %path was interpreted as the FOR variable %p followed by the text ath, not what was intended. To get around this, use a different letter or a longer name for the FOR variable, or use square brackets around the variable name, as shown in the examples below, any one of which accomplishes the original goal:

 

for %p in (a: b:) path %[path];%p

for %x in (a: b:) path %path;%x

for %px in (a: b:) path %path;%px

 

If the name of the FOR variable contains more than one character, it is created in the environment, and erased when FOR is completed, whether or not a variable by that name existed before the FOR. It  cannot be modified with the SET, ESET, or UNSET commands. If you already had a variable with that name, it will no longer be accessible. For example, a command that begins

 

for %path in ...

 

will write over your current PATH setting, then erase the PATH variable completely when FOR is done.

 

Command may also use the FOR variable with the special syntax of CMD described in Special syntax for CMD compatibility.

 

The following example uses FOR with variable functions to delete the .BAK files for which a corresponding .TXT file exists in the current directory (this should be entered on one line):

 

for %file in (*.txt) del %@name[%file].bak

 

The above command may not work properly on an LFN drive, because the returned FILE variable might contain white space. To correct this problem, you need two sets of quotes, one for DEL and one for %@NAME:

 

for %file in (*.txt) del "%@name["%file"].bak"

 

You can use command grouping to execute multiple commands for each element in set. For example, the following command copies each .WKQ file in the current directory to the D:\WKSAVE directory, then changes the extension of each file in the current directory to .SAV:

 

[for %file in (*.wkq) (copy %file d:\wksave\ & ren %file *.sav)

 

or (in a batch file):

 

for %file in (*.wkq) (

 copy %file d:\wksave\

 ren %file *.sav

)

 

In a batch file you can use GOSUB to execute a subroutine for every element in set. Within the subroutine, the FOR variable can be used just like environment variable. This is a convenient way to execute a complex sequence of commands for every element in set without CALLing another batch file.

 

One unusual use of FOR is to execute a collection of batch files or other commands with the same parameter. For example, you might want to have three batch files all operate on the same data file. The FOR command could look like this:

 

for %cmd in (filetest fileform fileprnt) %cmd datafile

 

This line will expand to three separate commands:

 

filetest datafile

fileform datafile

fileprnt datafile

 

FOR statements can be nested.

 

LEAVEFOR

 

The special keyword LEAVEFOR can be used inside a FOR command group. LEAVEFOR terminates the current FOR processing and continues with the line following the FOR command, in a manner similar to that of the LEAVE keyword in a DO command.

 

for %i in (*) (

...

if "%i" == "xyz.abc" leavefor

 ...

)

 

Options:

 

/A:Process only those files that have the specified attribute(s). /A: will be used only when processing wildcard file names in set. It will be ignored for filenames without wildcards or other items in set. See Attribute Switches for information on the attributes which can follow /A:.

 

For example, to process only those files with the archive attribute set:

 

for /a:a %f in (*) echo %f needs a backup!

 

Default: /A:-D-H-S, i.e. include only files without the hidden and system attributes.

 

You can specify /A:= to display a dialog to help you set individual attributes.

 

/DOnly return subdirectories, excluding "." and ".." .

 

/FReturn one or more words or tokens from each line of each file in set. The /F option can be followed by one or more options in a quoted string which control how the parsing is performed. See Parsing Text From Files.

 

/HSuppresses the assignment of the "." and ".." directories to the FOR variable when directories are explicitly included using the /A: option.

 

/I"text"Select filenames by matching text in their descriptions. See Description Ranges.

 

/LInterpret the three values in set as the start, step, and end values of a counted loop. See Counted FOR Loops.

 

/NjDon't recurse into symlinks or junctions (see /R).

 

/O:...Sort the files before processing.

 

You may use any combination of the sorting options below. If multiple options are used, the listing will be sorted with the first sort option as the primary key, the next as the secondary key, and so on:

 

nSort by filename and extension, unless e is explicitly included.
-Reverse the sort order for the next sort key
aSort names and extensions in standard ASCII order, instead of numerically when numeric substrings are included in the name or extension.
cSort by compression ratio
dSort by date and time (oldest first); also see /T:acw
eSort by extension
gGroup subdirectories first, then files
iSort by description
oSort by owner
rReverse the sort order for all options
sSort by size
tSame as d
uUnsorted
zSame as s

 

The /O:... option saves all of the matching filenames and then performs the requested operation. This avoids the potential problem of processing files more than once.

 

/R [path]Look in the current directory and all of its subdirectories for files in set. If the /R is followed by a directory name, look for files in that directory and all of its subdirectories. Warning: if the directory name includes special characters, including "%" to indicate an environment variable, it must be enclosed in double quotes ("). /R supports Windows shell folder names; see CDD for details.

 

/T"text"Specify the delimiters to be used when parsing a string set.

 

/WThe FOR set is to be processed as filenames, even if no wildcards are detected. (This is useful if you want to use regular expressions with FOR.)