The GroupMembershipTracker.bat script uses two tricks that you’ll want to add to your scripting toolbelt. The For command is a powerful tool to use in shell scripting, but it has a limitation: It can't parse files that have spaces in their path. My first trick is a way to work around that limitation.
Just for review, the For /f command is useful in many ways, but it has three primary uses in my scripts. First, I use it to parse a string and break it into tokens or pieces (then to reverse them, so you can see how the tokens can be manipulated):
For /f "tokens=1,2" %%i in ("Hello Fred") Do Echo %%j %%i
Second, I use it to run the Dir command and break the command’s output into tokens. In the Echo command that follows, I use only the first token (%%i). Note that when you run a command inside a For loop, you must encapsulate it within single quotes.
For /f "tokens=1,2,3,4" %%i in ('Dir /b C:\windows') Do Echo %%i
Third, I use it to parse a file line by line and break each line into tokens:
For /f "tokens=1,2,3,4" %%i in (C:\spreadsheet.txt) Do Echo %%i
A limitation of using For to parse files is that spaces in the file path (e.g., C:\My Files\spreadsheet A.txt) will cause For to fail. The technique of enclosing the file path in double quotes doesn't work because it causes For to interpret the filename as a string. You've probably lived with this limitation by avoiding spaces in your paths. I've recently discovered a couple of workarounds.
Using the Findstr or Sort command in your script reinstates the ability to use double quotes to handle path spaces—without causing a For failure. I've used this technique in the GroupMembershipTracker.bat script. In some circumstances, the Sort command can change output. For example, if you're working on a list of numbers or dates, Sort might change the order in undesirable ways. The Findstr command doesn't reorder the output. This sample command shows how to use Sort to overcome the problem with spaces in the path:
For /f "tokens=1,2,3,4" %%i in ('Sort ^< "C:\My Files\spreadsheet A.txt"') Do Echo %%i
And this sample command shows how to use Findstr to overcome the problem:
For /f "tokens=1,2,3,4" %%i in ('Findstr /I "\[A-Z0-9\]" "C:\My Files\spreadsheet A.txt"') Do Echo %%i
If you use Windows XP or Windows 2000, you can use the new usebackq option with the For command to conquer the space problem in filenames. Although spaces typically aren’t a problem when you use the For command to parse literal strings and command output, let’s look at how to use the usebackq option in these instances as well. When you use the usebackq option, you must enclose the string that has spaces in either single quotes (if the string is a literal string); grave accents, or back ticks (if the string is a command); or double quotes (if the string is a filename).
Literal strings. If the literal string you want to parse has spaces, you can include the usebackq option in your command and enclose the string in single quotes (‘). For example, here's how to use the usebackq option when you want to break the string Hello Fred into tokens:
For /f "usebackq tokens= 1,2" %%i in (‘Hello Fred’) Do @Echo %%j %%i
Because this usage of the usebackq option causes some trailing error output, I don't recommend this technique. I’m discussing this usage only because the For command's online Help file covers it. To cleanly break up literal strings, you should not use the usebackq option; instead, use double quotes.
Command output. If the command you want to execute has spaces, you can include the usebackq option and enclose the command in back ticks. For example, here's how to use the usebackq option when you want to parse the output of the Dir command:
For /f "usebackq tokens= 1" %%i in (`Dir /b C:\windows`) Do @Echo %%i
Using the usebackq option with back ticks is the equivalent of enclosing the command in single quotes without the usebackq option.
Filenames. If the filename you want to use has spaces, you can include the usebackq option and enclose the filename in double quotes. For example, here's how to use the usebackq option when you want to parse a file and break each line into tokens:
For /f "usebackq" %%i in ("C:\:My Files\spreadsheet A.txt") Do @Echo %%i
My second trick provides a way for a script to automatically locate the folder in which it resides. Typically, I put each of my scripts in a separate folder, along with any input files, output files, and utilities that the script uses. At the top of each script, I indicate where these various files reside. Alternatively, you can use a Call command to determine the script’s directory path, as Web Listing A shows.
After you include such Call code in your script, you can point to all the files the script depends on or creates, without needing to hard-code those files into the script. If you change the script's path location to a different folder, the script will detect the change and alter the path it uses for the input and output files. This approach is particularly useful when Task Scheduler will be launching the script.