Windows BATCH Scripting_Loops

Table of Contents

Loops ...... 2

Loops Multiple File Example ...... 5

Loops Directory Example ...... 8

Loops Multiple Lines in a File Example ...... 9

Loops Running a Multiple Times ...... 10

For Loops ...... 11

Tokenizing Loop Example -1 ...... 13

Tokenizing Loop Example -2 ...... 16

Notices ...... 17

Page 1 of 17 Loops

Loops

A core component of scripts – allow one thing many times Windows batch scripts use “FOR – DO” and has 4 different constructs depending on which switches are used with “FOR” • Multiple Files – perform one command on each file FOR %a IN (file(s)) DO (commands) • Multiple Directories – perform one command on each directory FOR /D %a IN {dirpath} DO (commands) • Multiple Lines IN a File – perform one command for each line FOR /F %a IN (filename) DO (commands) • Run a Command Multiple Times – perform command many times FOR /L %a IN (x, y, z) DO (commands) Loop variables ARE case sensitive.

36

**036 There is a looping construct within BATCH. The FOR loop. It's one of the core components of scripting. It's very powerful. When you think of being able to do multiple things rapidly, repetitively, you have to do some sort of looping. In this case, this will be the FOR loop. Uses the FOR - DO. And there's, like, there's four different constructs depending on the switch you use for the type of result or the type of looping that you'd like to have happen.

On the first one here, when you have multiple files and you'd like to perform a command on each of

Page 2 of 17 them, you go ahead and do the FOR. So the key words are FOR, IN and DO. The construct for this is that this particular variable, the %a, can actually be any letter. It doesn't have to be a "a". but I would like to point out, the difference between loop variables and the user made or user declared variables is that loop variables are case sensitive. If you accidentally type capital A% it will not give you the results that you're looking for.

So this is a key point to note of is that if you do have a looping variable, make sure when you go to output it, if you're going to do something with it a little bit later, make sure it's the same one. Again, it doesn't have to be a letter by itself. Could be something else, but... And then you definitely need the FOR, the IN and the DO portions of it. And then you'll want to put the files within the parentheses, file or files. I mean, if it's only one you can do multiple commands to that one file as well. If you have multiple directories that you would like to do something with, perform a command in each of those directories, you use the FOR /D. Same basic format with the variable here, and then IN, the directory that you'd like to, excuse me, like to loop through, and then the commands at the end that you would like to have run.

So if you have multiple lines in a file that you would like to perform a command against, you would use the /F FOR loop. And again, the same

Page 3 of 17 basic format, but instead of the directory path you'll put the file name and for each of those lines it'll go ahead and run that command for you. And it knows to stop with the end of that particular file so you don't have to worry about it continuing on.

And then there's a, if you have to run a command multiple times, and perform it multiple, there is this FOR loop with a /L. And so there's a little- -this is somewhat similar to a more traditional FOR loop, and this is where the numbering sort of thing happens. But the x, y, and z are actually the value you'd like to at, the step, and then the stop value that you'd like it to stop at. So this could be like 1, 1. So just keep iterating to, like, say 10, and it'll just do 11 times, right? So just remember the three S-T's if you will. The start, the step and the stop is what you'll need in here. If you need to, you know, count by fives, if you need to count by some other value, you can go ahead and do that in here and it'll run those commands based on that. And you can use the, this variable, becomes the value of whatever this number starts at or during the iterations it becomes a number that this step tells you, this NEXT. So if you need to reference it and use it, if you're counting and you want to show that number as it's iterating, you can reference with the %a and it'll show the value as it's looping what--as it steps up or... And you can use that as you need to in your script.

Page 4 of 17 Any questions on this? Ah, yes, Franklin?

Student: You have multiple files and you have files in parentheses. With the file, are they separated by a comma or space?

Instructor: Yes. You would put a comma between if you have multiple, that's correct. Any other questions? Okay.

Loops Multiple File Example

Loops Multiple File Example

Note the double percents Output (%%) – use in a batch file, but not on the command line

Wildcards could also be used here instead of actual file names.

37

**037 Okay. So here is the example of exactly what--well, I apologize. I seem to have misspoken. I thought it was a

Page 5 of 17 comma that separates those, but it's a in this case FOR and the %%a. So there is a difference when you use the information from a BATCH file directly into the command line. You only need a single percent before these looping variables. The interpreter, the reason for this, is when you use it in a BATCH file, when the interpreter goes through the very first time, it immediately tries to assign it a value. So that first percent is almost like an escape character, if you're familiar with escaping a particular keyword or character. It's kind of like escaping that second param and telling it, "Hold off right now. We're going to use it a little bit later." So take a step back on that one for just a second. But that's the reason for the double % within this script.

And so you have your three different, in this case, three different files that you'd like to do these particular things for and then there's another IF construct. If that file exists, you go ahead and out the file name. ELSE. If it's not, the File NOT Found, and the name of that that found.

So it is possible to use wildcards here, meaning that if you would like to do it for all but .tmps you can do the *.tmp or *.doc or whatever it is that you would like to do these on. You don't necessarily have to put every single one of those out there. You can, if you have a particular extension that you want to do the commands to, you can use that.

Page 6 of 17 So you see the output here. Course, you don't know what's in this particular directory, but it found these two and it did not find the last one, file.tmp.

Yes?

Student: What's the significance of the indentations or anything? Is that just for aesthetics?

Instructor: It is aesthetics, in a sense, but it's also readability. It just lets you know that FOR loop is going to run those things. That's correct. And that's pretty much a best practice. It's...

Student: I didn't know if it had a function other than that.

Instructor: Right.

Student: Okay.

Instructor: Yeah. Correct. Some languages explicitly like tabbing or certain things happen based on that. In this case, it really wouldn't matter if everything was pretty much all in a line. Course, the readability at that point goes out the window. So this is definitely for helping the, understanding how it runs, and what happens in this particular loop.

Page 7 of 17 Loops Directory Example

Loops Directory Example

:

Output

38

**038 Excuse me. Here's one for directories, multiple directories. Or the /D. Lets it know that it's this type of FOR loop. And in this case, it's actually looking for anything, any directory, that starts with a capital, or a letter "V," I should say. Sorry. That's what the V* is for. And then it'll go and echo out V Directory Found. And it'll actually, every one of those that it finds, excuse me, will be output to the screen. And in this case it found the VMs directory and the vTest directory. That can be helpful as well.

Page 8 of 17 Loops Multiple Lines in a File Example

Loops Multiple Lines in a File Example

:

Output

Input File

39

**039 So here's one. Multiple lines within a file that you would like to do a certain thing to or run commands against. The /F lets the interpreter know that this is the type that you'd like. And then you go ahead and put in your file that you would like to iterate through. Each of the lines. And in this case, the fileIn.txt happens to have three IP addresses within it. And the output puts Line in File and it actually, you see it referenced, as the %%a, and it just puts the value out to the screen.

Page 9 of 17 Loops Running a Command Multiple Times

Loops Running a Command Multiple Times

Output

Start Step Stop

40

**040 All right. And then this is the Running a Command Multiple Times. A little bit more like the traditional FOR loop. And again the /L lets the interpreter know that this is the type of FOR loop that you'd like, and it is expecting those three values, separated by commas. And again, that's the three S-T's the start, stop, or start, step and stop. And for this particular example it's a real simple print to the screen, outputting the value as it steps through them. This one happened to be counting by 10. Again, you can do one, two, whatever it is that you need, for your particular script.

Page 10 of 17 And this can be very helpful if you, say, need to do something to particular host, you can make yourself an IP list and you can also run it based on the value that you put in there. If you need it to be, you know, the last octet has to be 100 through 150 or whatever it is. You can start it at 100, you can do a step by 1 and you can edit 150. And as it iterates you can use it within your script somewhere that you reference the %a and it'll also do it to that particular host. So in that sense it can be powerful.

For Loops

For Loops

Support rudimentary string “tokenizing” • Allows separation of the input variable into pieces based on a delimiter Use the “FOR” command’s “tokens” and “delims” parameters • Tokens specifies how many pieces • Delims specifies how the pieces are separated For example

10.10.1.1,Admin-PC,The Administrators PC 10.10.1.10,Janes-PC,Janes workstation

Tokens: 1, 2* Delims: “,”

41

**041 Okay. FOR Loops. Has a

Page 11 of 17 somewhat rudimentary tokenizing capability. Excuse me. This allows you to separate pieces of your input into what they call tokens. So this is a little bit of an eye chart. I'm not sure how well you can see this, but this happens to have a couple strings, but each of these pieces of information has a comma that separates certain parts of it, so you can use what they call delims or delimiters, set those to commas, and you can tell it to set the tokens that you'd like to interact with as 1. So in this case this would be the first one, and then the second one. And the rest, so you can treat that as the star means the rest.

So it'll treat it pretty much like there's 2 in and some others. If you need to interact with 5 and 7, if you have that many, well, then it knows exactly that that's exactly the pieces that you want to interact with. So this seems kind of simple right now, 1, 2; 1, 2, 3. You can certainly make it 1, 2, 3, 4. But sometimes, if you know in your list of things that are separated, it could be comma, it could be a space also, or some other thing. But depending on what you tell the interpreter, you may want this to be slightly different. But this is just kind of a simple case of 1, 2 and all the rest.

Page 12 of 17 Tokenizing Loop Example -1

Tokenizing Loop Example -1

You could do this from the command line… Drop the extra “%”. Output

42

**042 So here's an example of using those delimiters on the exact same input information. That's what I was pointing at on the previous slide, is that you have a IP address in this case separated with a comma, followed by the Admin-PC, and then a comma and then Administrators PC.

Yes?

Student: What was the purpose of the asterisk after the 2 on tokens?

Instructor: That just lets them know that you would like to deal with the rest of it. It's kind of just one other, one more token, the rest of it.

Page 13 of 17 And in this case it's like we don't even care, there's only a third token anyway. So you could have easily have put a comma 3 if you wanted to. It just kind of depends on whether or not you want to interact with the rest. You can break that down a little bit. So the star essentially means--

Student: The asterisk means don't bother with the rest?

Instructor: Well, not so much don't bother with it, but I think treat the rest of it as one token.

Student: After the first two.

Instructor: That's correct. In this case. So you could've done a 1, 2, 3* and it could've done 3 and then if there was anything past three--

Student: So there would've been four items.

Instructor: That would've been a fourth item. And you could've treated the rest, right, as...

Student: Anything past that is still part of the fourth.

Instructor: It's considered part of the fourth, right. It's mostly for if you really don't care about, you know, in that sense, the rest of it. You'll just say, "Yep," and, "Just treat it as the fourth, please."

So we're using the /F, because we want to go through this particular

Page 14 of 17 file, and then we, for this you use the quotes around this and you use the word, keyword tokens and you use the =, and for this it's the 1, 2*. And we're using the comma as the delimiter, so you definitely need that right there, right after the /F. And then once again you're accessing the variable with the %%a in this particular file, and so here's another key point for this is that when you tokenize and you tell them you want to do 1 and 2, or 3 and 4, whatever it is, implicitly it knows that token 1 is the a. So this is one case where you want to access a because it knows that the first token will be represented by the a, the second token, in this case, the name of the PC, it might be a hostname, oh, yeah, hostname, is the b and then the third one will be a c. So...

To make a point, if you had chosen the fourth token and the sixth token, when you go to reference the fourth, it will still, since it's the only one or the first one you want to reference, it'll still be the a. Does that make sense? I hope that isn't too confusing. So implicitly it already knows to assign the first token will be %%a for you when you want to reference it. But if you do a different set of tokens, if you just want to reference some other token other than just the first and the second and the third, it will still show the very first token that you're trying to get at will be the a token.

And you can run this from the command line as well.

Page 15 of 17 Tokenizing Loop Example -2

Tokenizing Loop Example -2

Process Note incrementing variable (a, b, c) • /F = for each line in the file • Tokenize string using a comma as a delimiter • Tokenize into 3 tokens: * = everything else on the line • ECHO sends output to the screen • %%a is first column in the file -> IP Address • %%b is second column in the file -> Hostname • %%c is EVERYTHING ELSE -> Comments

43

**043 Okay. It's example. This is pointing out the star that we had just, John had just asked about, when we were assigning the tokens. The c, %%c is everything else. In this case, comments. So technically if it were a bunch of even comma separated maybe sentences or something like that, this would put out the rest of the entire input line that's there. So that's just for clarification. You know, /F is for the file with multiple lines, right? And we are tokenizing. And using the comma as the delimiter. And in this case, the echo does show up. Put it out to the screen.

Page 16 of 17 Notices

Notices

© 2015 Carnegie Mellon University This material is distributed by the Software Engineering Institute (SEI) only to course attendees for their own individual study. Except for the U.S. government purposes described below, this material SHALL NOT be reproduced or used in any other manner without requesting formal permission from the Software Engineering Institute at [email protected]. This material was created in the performance of Federal Government Contract Number FA8721-05-C- 0003 with Carnegie Mellon University for the operation of the Software Engineering Institute, a federally funded research and development center. The U.S. government's rights to use, modify, reproduce, release, perform, display, or disclose this material are restricted by the Rights in Technical Data- Noncommercial Items clauses (DFAR 252-227.7013 and DFAR 252-227.7013 Alternate I) contained in the above identified contract. Any reproduction of this material or portions thereof marked with this legend must also reproduce the disclaimers contained on this slide.

Although the rights granted by contract do not require course attendance to use this material for U.S. government purposes, the SEI recommends attendance to ensure proper understanding.

THE MATERIAL IS PROVIDED ON AN “AS IS” BASIS, AND CARNEGIE MELLON DISCLAIMS ANY AND ALL WARRANTIES, IMPLIED OR OTHERWISE (INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, RESULTS OBTAINED FROM USE OF THE MATERIAL, MERCHANTABILITY, AND/OR NON-INFRINGEMENT).

CERT ® is a registered mark owned by Carnegie Mellon University.

6

Page 17 of 17