• Aucun résultat trouvé

Parsing Passed Text into an Array

In this example, you work through a script that creates a dynamic array used to hold information parsed from the Windows 2003 setup log file, Setuplog.txt. One issue to note: if you’re working on an upgraded version of Windows 2003, your Setuplog.txt file is contained in the WINNT directory. If you’re working with a fresh installation, the Setuplog.txt file is contained in the Windows directory. The reason for this is that beginning with Microsoft Windows XP, the name of the default Windows directory was changed from WINNT to Windows. However, in an upgrade, the Windows directory cannot be renamed without breaking a whole bunch of applications.

In our script called SearchTXT.vbs (which is on the companion CD), you create a dynamic array and set the initial size to zero. You next make a connection to the file system object and open the Setuplog.txt file, contained in the Windows directory, for reading. Once the Setuplog.txt file is opened for reading, you define a search string of

“Error” and use the InStr command to look through each line. If the string “Error” is found on the line being examined, the line with the error is written into the array. You then increment the next element in the array in case you find another line with the string “Error” in it. After you go through the entire text file, you use a For…Next loop and echo out each element of the array. The script concludes with a friendly “all done”

message. The code for SearchTXT.vbs follows:

Option Explicit

Set objTextFile = objFSO.OpenTextFile _

For i = LBound(arrTxtArray) To UBound(arrTxtArray) WScript.Echo arrTxtArray(i)

Next

WScript.Echo(“all done”)

Header Information

The Header information section of SearchTXT.vbs contains few surprises at this junc ture. The important aspect in this section is the listing of all the variables contained in SearchTXT.vbs. This declaring of the variables provides a blueprint for understanding the script. Each variable and its use is listed in Table 5-1. The Header information sec tion of the script is listed here:

Option Explicit

Table 5-1 Variables Declared in SearchTXT.vbs

Variable Use

arrTxtArray() Declares a dynamic array€

myFile Holds the file to open up€

SearchString Holds the string to search for€

objTextFile Holds the connection to the text file€

strNextLine Holds the next line in the text stream€

intSize Holds the initial size of the array€

objFSO Holds the connection to the file system object€

i Used to increment intSize counter€

Reference Information

The Reference information section of the script is used to assign values to many of the variables that are declared in the Header information section. The Reference informa tion section of SearchTXT.vbs follows:

intSize = 0

myFile = “c:\windows\setuplog.txt"

SearchString = “Error"

Const ForReading = 1

Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objTextFile = objFSO.OpenTextFile _

(myFile, ForReading)

IntSize is used to hold the value of the initial size of the dynamic array used in this script. It is set to zero because you do not know how many items you will have in your dynamic array. You start with the value of zero, and then you later increase the array to the required size as you read through the log file. A different approach would be to create an array that is much larger than you think you’d need, and then populate the array with the items gathered from the log file. However, there are at least two prob lems with this approach:

Creating an array that is too large wastes memory resources.

Creating an array that is too large results in too many elements that have a zero value.

The myFile variable is assigned to the physical location of the log file you want to parse. In this instance, you are looking at the Windows Server 2003 setup log file con tained in the Windows directory. This is one modification you will need to make to your script—changing the location and name of the log file you want to parse. By cre ating a variable called myFile, and by assigning it to a log file in the Reference infor mation section of the script, you make it easy to modify the script for future use. By simply changing the file you want to parse, you can use this script to peruse many dif ferent log files.

SearchString is the variable that holds the string of letters you want to glean from the log file. As the script currently stands, you are searching for the word “Error” in the Win dows Server 2003 setup log file. By searching for “Error,” you create an array that holds all the errors that occurred during the installation of the Windows Server 2003 server.

Create a constant called ForReading and set it to the value of 1. Then create a FileSys­

temObject and use the ForReading constant to open the log file. When you open a text file using a FileSystemObject, you must tell VBScript whether you’re going to open the file and read from it, or open the file and write to it. In your script, you need only to be able to read from the file to find the lines containing the word “Error.”

See Also For more information about creating and using constants, refer to Chapter 2,

“Getting in the Loop.”

You now use the Set command to assign the variable objTextFile to be equal to the command that opens the text file for reading. Here is the syntax for this command:

Set New variable Command Filename Read or write Set objTextFile objFSO.OpentextFile myFile ForReading

Worker Information

The Worker information section of the SearchTXT.vbs script, shown in the following code, is where you create a text-processing engine. This engine is made up of the fol lowing components:

Do Until...Loop

If...Then loop

ReDim Preserve

Do Until objTextFile.AtEndofStream strNextLine = objTextFile.ReadLine If InStr (strNextLine, SearchString) Then

ReDim Preserve arrTxtArray(intSize) arrTxtArray(intSize) = strNextLine intSize = intSize +1

End If Loop

objTextFile.Close

The Do Until…Loop is used to walk through the text stream that comes from the con nection to our setup log file. The Do Until structure controls the entire process and will continue working until it comes to the end of the data stream (which incidentally occurs when you reach the bottom of the text file).

The variable strNextLine is assigned to the line of text that comes from the text file when you use the ReadLine command on objTextFile. (Remember that you defined objTextFile to be the handle you get back from the setup log file. You do this by using the read-only version of the OpenTextFile command in the Reference information sec tion of the script.)

You use an If…Then structure to look through strNextLine for the value contained in the variable you called SearchString. In the Reference section, you assigned the value

of “Error” to the variable SearchString. You use the InStr command to search strNext-Line for the text string “Error.” The InStr command has the following syntax:

InStr Starting position String being String searched Compare mode

(optional) searched for (optional)

InStr strNextLine SearchString

When using InStr, the starting position is the first character in the text string to be searched. It is important to remember that the InStr command is not zero-based. A position that is actually 38 spaces away will be reported as 38. The optional starting position field of the InStr command is quite useful when parsing certain log files that begin each line with a time stamp or other information that makes the file difficult to parse. By skipping past the time stamp, you can parse the line more easily.

Note Many of the commands you use in VBScript are, for whatever reason, zero-based, which means that you start counting at zero. OK, that’s groovy. But now you come to InStr, which is not zero-based. A position that is 12 spaces away will be reported as 12. Forget this fact, and your scripts will act really strange.

If the InStr command finds the search text in the search string, you use ReDim Preserve to expand the array by one element. ReDim Preserve actually performs two tasks. The first is to resize the array, and the second is to make sure you don’t lose any data when the array is resized. The arrTxtArray(intSize) = strNextLine line adds the value con tained in strNextLine to the arrTxtArray element identified by the intSize variable. The intSize = intSize +1 construct increases the intSize variable by 1. You’ll use this variable to add one more element to your array when the InStr command finds an additional line containing the word “Error” in the text string.

When you reach the end of the data string, you use End If to end the If loop and the objTextFile.Close command to close the text file. This step is not really required, because the text file automatically closes when the program quits; however, this step is considered good practice and can prevent potential file-locking problems in the future.

Output Information

After you load the array with the information gathered from the setup log file, you really have accomplished only half of the task. This is because constructing an array and not using it is pretty well useless. In this script, you’re going to simply echo out the

lines found that contain the word “Error” in them. In many cases, echoing the errors out is sufficient. In later chapters, you’ll learn how to save this information to a text file for future manipulation if desired. Because your script is modular in its design, you could easily replace this output information section with one that saves to a text file or creates a Web page, or one that creates and sends an e-mail.

You use a For…Next loop to work through the lower boundary and the upper bound ary of your dynamic array. Once you get to each new element in the array, you use the WScript.Echo command to print to the screen the data contained in that element of the array. Then use the Next command to go back and read the next element in the array.

You continue to do this Until reaching the upper boundary of the array. Once you reach the end of the array, you use WScript.Echo to let yourself know that the script completed successfully. This section of the script is listed here:

For i = LBound(arrTxtArray) To UBound(arrTxtArray) WScript.Echo arrTxtArray(i)

Next

WScript.Echo(“all done”)

Quick Check

Q. What is the advantage of using a dynamic array?

A. You can expand a dynamic array when a new element is needed. This saves memory and is more efficient.

Q. How is ReDim Preserve used?

A. ReDim Preserve is used to resize a dynamic array while saving the data that is contained in the element.