Command Line Iteration Statements

 < Day Day Up > 



When you want to execute a command or a series of commands repeatedly, you’ll use the for statement. The for statement is a powerful construct, and before you skip this section because you think you know how the for statement works, think again. The for statement is designed specifically to work with the command-shell environment and is very different from any other for statement you may have worked with in other programming languages. Unlike most other for statements, the one in the command line is designed to help you iterate through groups of files and directories, and to parse text files, strings, and command output on a line-by-line basis.

Iteration Essentials

The command shell has several different forms of for statements. Still, the basic form of all for statements is

for iterator do (statement)

Here the iterator is used to control the execution of the for loop. For each step or element in the iterator, the specified statement is executed. The statement can be a single command or multiple commands chained, piped, or grouped within parentheses.

The iterator usually consists of an initialization variable and a set of elements to execute against, such as a group of files or a range of values to step through. Initialization variables are essentially placeholders for the values you want to work with. When you work with initialization variables, keep in mind the following:

  • Iterator variables only exist within the context of a for loop.

  • Iterator variable names must be in the range from a to z or A to Z, such as %%A, %%B, or %%C.

  • Iterator variable names are case-sensitive, meaning %%a is different from %%A.

As Table 3-4 shows, the various structures used with for statements have specific purposes and forms. When the for statement is initialized, iterator variables, such as %%B, are replaced with their actual values. These values come from the element set specified in the for statement and could consist of a list of files, a list of directories, a range of values, and so on.

Table 3-4: Forms for Iteration

Iteration Purpose

Form Syntax

Sets of files

for %%variable in (fileSet) do statement

Sets of directories

for /D %%variable in (directorySet) do statement

Files in subdirectories

for /R [path] %%variable in (fileSet) do statement

Stepping through a series of values

for /L %%variable in (stepRange) do statement

Parsing text files, strings, and command output

for /F [“options”] %%variable in (source) do statement

Real World

The forms provided are for scripts. You can also use for statements interactively at the command line. In this case, use %variable instead of %%variable. Beyond this, for statements within scripts or at the command line are handled in precisely the same way.

Stepping through a Series of Values

The “traditional” way to use for statements is to step through a range of values and perform tasks using these values. You can do this in the command shell and the basic syntax of this type of for loop is

for /l %%variable in (start,step,end) do (statement)

This type of for statement operates as follows. First, the command shell initializes internal start, step, and end variables to the values you’ve specified. Next, it compares the start value with the end value to determine if the statement should be executed, yielding a true condition if the start value can be incremented or decremented as specified in the step and a false condition otherwise. In the case of a true condition, the command shell executes the statement using the start value, then increments or decrements the start value by the step value specified and afterward, repeats this process. In the case of a false condition, the command shell exits the for statement, moving on to the next statement in the script.

Consider the following example that counts from 0 to 10 by 2’s:

for /l %%B in (0,2,10) do echo %%B 

The output is

0
2
4
6
8
10

You can also use a negative step value to move through a range in decreasing values. You could count from 10 to 0 by 2’s as follows:

for /l %%B in (10,-2,0) do echo %%B

The output is

10
8
6
4
2
0

Iterating Through Groups of Files

A more powerful way to use for statements in the command shell is to use them to work with files and directories. The for statement syntax for working with groups of files is

for %%variable in (fileSet) do (statement)

Here you use fileSet to specify a set of files that you want to work with. A file set can be

  • Individual files as specified by a filename, such as MyFile.txt

  • Groups of files specified with wildcards, such as *.txt

  • Multiple files or groups of files with spaces separating file names, such as *.txt *.rtf *.doc

Now that you know the basic rules, working with files is easy. For example, if you want to list all text files in an application directory, you can use the following command in a script:

for %%B in (C:\Working\*.txt) do (echo %%B)

Here B is the initialization variable, C:\Working\*.txt specifies that you want to work with all text files in the C:\Working directory, and the statement to execute is echo %%B, which tells the command shell to display the current value of %%B each time it iterates through the for loop. The result is that a list of the text files in the directory is written to the output.

You could extend this example to examine all .txt, .rtf, and .doc files like this:

for %%B in (%AppDir%\*.txt %AppDir%\*.rtf %AppDir%\*.doc) do (echo 
%%B)

You can also use multiple commands using piping, grouping, and chaining techniques, such as

for %%B in (%AppDir%\*.txt %AppDir%\*.rtf %AppDir%\*.doc) do (echo %%B 
& move C:\Data)

Here you list the .txt, .rtf, and .doc files in the location specified by the AppDir variable and then move the files to the C:\Data directory.

Iterating Through Directories

If you want to work with directories rather than files, you can use the following for statement style:

for /d %%variable in (directorySet) do (statement)

Here you use directorySet to specify the group of directories you want to work with. Iterating directories works exactly like iterating files, except you specify directory paths rather than file paths. If you wanted to list all the base directories under %SystemRoot%, you would do this as follows:

for /d %%B in (%SystemRoot%\*) do echo %%B

On Windows Server 2003, a partial result list would be similar to

C:\Windows\AppPatch
C:\Windows\Cluster
C:\Windows\Config
C:\Windows\Cursors
C:\Windows\Debug

Note

Note that the for /d loop iterates through the specified directory set but doesn’t include subdirectories of those directories. To access subdirectories (and indeed the whole directory tree structure), you use for /r loops, which I’ll discuss in a moment.

You can specify multiple base directories by separating the directory names with spaces, such as

for /d %%B in (%SystemRoot% %SystemRoot%\*) do echo %%B

Here you examine the %SystemRoot% directory itself and then the directories immediately below it. So now your list of directories would start with C:\Windows (if this is the system root) and continue with the other directories listed previously.

You can also combine file and directory iteration techniques to perform actions against all files in a directory set, such as

for /d %%B in (%APPDATA% %APPDATA%\*) do (
@for %%C in ("%%B\*.txt") do echo %%C)

The first for statement returns a list of top-level directories under %APPDATA%, which also includes %APPDATA% itself. The second for statement iterates all .txt files in each of these directories. Note the @ symbol before the second for statement. As with if statements, this indicated the second for statement is nested and is required to ensure proper execution. The double quotations with the file set ("%%B\*.txt") ensure that directory and file names containing spaces are handled properly.

Because you’ll often want to work with subdirectories as well as directories, the command shell provides for /r statements. Using for /r statements, you can examine an entire directory tree from a starting point specified as a path. The syntax is

for /r [path] %%variable in (fileSet) do (statement)

Here path sets the base of the directory tree you want to work with, such as C:\. The path is not required, however, and if the path is omitted, the current working directory is assumed.

Using a for /r statement, you could extend the previous example to list all .txt files on the C: drive without needing a double for loop, as shown here:

for /r C:\ %%B in (*.txt) do echo %%B

As you can see, for /r statements are simpler than double for loops and more powerful. You can even combine /r and /d without needing a double loop. In this example, you obtain a listing of all directories and subdirectories under %SystemRoot%:

for /r %SystemRoot% /d %%B in (*) do echo %%B

Parsing File Content and Output

Just as you can work with file and directory names, you can also work with the contents of files and the output of commands. To do this, you’ll use the following for statement style:

for /f ["options"] %%variable in (source) do (statement) 

Here, options sets the text matching options, source specifies where the text comes from, which could be a text file, a string, or command output, and statement specifies what commands should be performed on matching text. Each line of text in the source is handled like a record where fields in the record are delimited by a specific character, such as a tab or a space (which are the default delimiters). Using substitution, the command shell then replaces placeholder variables in the statement with actual values.

Consider the following line of text from a source file:

William Stanek Engineering Williams@adatum.com 3408

One way of thinking of this line of text is as a record with five fields:

  • First Name William

  • Last Name Stanek

  • Department Engineering

  • E-Mail Address Williams@adatum.com

  • Phone Extension 3408

To parse this and other similar lines in the associated file, you could use the following for statement:

for /f "tokens=1-5" %%A in (current-users.txt) do (
@echo Name: %%A %%B Depart: %%C E-mail: %%D Ext: %%E)

Here you specify that you want to work with the first five fields (token fields separated by spaces or tabs by default) and identified by iterator variables, starting with %%A, which means the first field is %%A, the second %%B, and so on. The resulting output would look like this:

Name: William Stanek Depart: Engineering E-Mail: Williams@adatum.com 
Ext: 3408

Table 3-5 shows a complete list of options that you can use. Examples and descriptions of the examples are included.

Table 3-5: Options for File Content and Command Output Parsing

Option

Description

Example

Example Description

eol

Sets the end-of-line comment character. Everything after the end-of-line comment character is considered to be a comment.

"eol=#"

Sets # as the end-of-line comment character.

skip

Sets the number of lines to skip at the beginning of files.

"skip=5"

Tells the command shell to skip lines 1 through 5 in the source file.

delims

Sets delimiters to use for fields. The defaults are space and tab.

"delims=,.:"

Specifies that commas, periods, and colons are delimiters.

tokens

Sets which token fields from each source line are to be used. You can specify up to 26 tokens provided you start with a or A as the first iterator variable. By default, only the first token is examined.

"tokens=1,3"

"tokens=2-5"

First example sets fields to use as 1 and 3. Second example sets fields 2, 3, 4, and 5 as fields to use.

usebackq

Specifies that you can use quotation marks in the source designator: double quotation marks for file names, back quotation marks for command to execute, and single quotation marks for a literal string.

"usebackq"

To see how additional options can be used, consider the following example:

for /f "skip=3 eol=; tokens=3-5" %%C in (current-users.txt) do (
@echo Depart: %%C E-mail: %%D Ext: %%E)

Here, three options are used. The skip option is used to skip the first three lines of the file. The eol option is used to specify the end-of-line comment character as a semicolon (;). Finally, the tokens option specifies that tokens 3 to 5 should be placed in iterator variables, starting with %%C.

With tokens, you can specify which fields you want to work with in many different ways. Here are some examples:

  • tokens=2,3,7 Use fields 2, 3, and 7.

  • tokens=3-5 Use fields 3, 4, and 5.

  • tokens=* Examine each line in its entirety and do not break into fields.

When you work with text files, you should note that all blank lines in text files are skipped and that multiple source files can be specified with wild cards or by entering the file names in a space-separated list, such as

for /f "skip=3 eol=; tokens=3-5" %%C in (data1.txt data2.txt) do (
@echo Depart: %%C E-mail: %%D Ext: %%E)

If a file name contains a space or you want to execute a command, specify the usebackq option and quotation marks, such as

for /f "tokens=3-5 usebackq" %%C in ("user data.txt") do (
@echo Depart: %%C E-mail: %%D Ext: %%E)

or

for /f "tokens=3-5 usebackq" %%C in (`type "user data.txt"`) do (
@echo Depart: %%C E-mail: %%D Ext: %%E)

Tip

Remember the backquote (`) is used with commands and the single quotation mark (‘) is used with string literals. In print, these characters no doubt look very similar. However, on a standard keyboard, the backquote (`) is on the same key as the tilde (~) and the single quotation mark (‘) is on the same key as a double quotation mark (“).

Note

In the second example, I use the TYPE command to write the contents of the file to standard output. This is meant to be an example of using a command with the backquote.

Speaking of quotation marks, you use quotation marks when you want to process strings and variable values. Here, you enclose the string or variable name you want to work with in double quotation marks to ensure the string or variable can be evaluated properly. You do not, however, need to use the usebackq option.

Consider the following example:

set value=All,Some,None
for /f "delims=, tokens=1,3" %%A in ("%VALUE%") do (echo %%A %%B)

The output is

All None



 < Day Day Up > 



Microsoft Windows Command-Line Administrator's Pocket Consultant
MicrosoftВ® WindowsВ® Command-Line Administrators Pocket Consultant
ISBN: 0735620385
EAN: 2147483647
Year: 2004
Pages: 114

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net