• Aucun résultat trouvé

Parsing Passed Text

One cool thing you can do with arrays is use them to hold the results of parsing a comma-separated value (CSV) file. With Windows Server 2003, you can easily create a CSV file from the event viewer. Right-click the log you are interested in, select Save As from the menu, and choose CSV File. Now, suppose you have a file such as a CSV (I included an application log from one of my test machines), and you’re trying to find out about MSI installer errors on that server. Well, you can try to weed through all those long lines of text or you can open it up in Microsoft Excel, or you can use a script to do the heavy lifting.

The ParseAppLog.vbs script follows:

If InStr ( strNextLine, ErrorString) Then ReDim Preserve arrTxtArray(intSize)

For i = LBound(arrTxtArray) To UBound(arrTxtArray) If InStr (arrTxtArray(i), “,”) Then

newArray = Split (arrTxtArray(i), “,”) WScript.Echo “Date: “ & newArray(0)

Just the Steps

To convert a CSV file into an array 1. Implement a CSV file for the source.

2. Use the InStr function to parse the data.

3. Use the file system object to connect to a data source.

4. Use a dynamic array to hold the data.

5. Use LBound and UBound to iterate through the array.

6. Use the Split function to break the text line into elements.

7. Add the new elements into a multidimensional array.

WScript.Echo “Time: “ & newArray(1)

WScript.Echo “Source: “ & newArray(2)& “ “& newArray(3) WScript.Echo “Server: “ & newArray(7)

WScript.Echo “Message1: “ & newArray(8) WScript.Echo “Message2: “ & newArray(9) WScript.Echo “Message3: “ & newArray(10) WScript.Echo “ “

End If Next

WScript.Echo(“all done”)

Header Information

The Header information section in ParseAppLog.vbs is similar to the Header section in the previous script. The variables utilized are listed in Table 5-2.

Table 5-2 Variables Declared in ParseAppLog.vbs

Variable Use

arrTxtArray() Declares a dynamic array€

appLog Holds the file to open€

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 the intSize counter€

ErrorString Holds the second search string used€

newArray New array created to sort the output€

Reference Information

The Reference information section is where you assign values to certain variables and define constants that are used in the script. Here is the Reference information section of the script:

intSize = 0

appLog = “C:\scriptingBook\BookScripts_VbScript\ch5\applog.CSV"

SearchString = “,"

ErrorString = “1004"

Const ForReading = 1

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

(appLog, ForReading)

Applog is used to point to the CSV file you want to parse. You use SearchString to spec ify that you want to look for commas. The ErrorString you are looking for in this script is 1004, which is an error from MSI installer. By changing the error message ID, you can use the script to look for everything from dropped IP packets from the ISA server to bad logon attempts from Windows Server 2003.

Important This technique won’t perfectly parse every CSV file in the world. Some are very complex and include commas and even line feeds within single pieces of data.

Although special rules for advanced parsing are beyond the scope of this chapter, you are unlikely to encounter this problem with normal application setup logs (and you definitely won’t see this in CSV files exported from the Event Viewer).

Worker Information

In the Worker information section of the script, things start to get a little interesting.

You begin by using a Do Until construction that looks for the end of the read-only text string coming from objTextFile. You then define strNextLine to be equal to what comes back from the readline command that we used on objTextFile. The magic begins when you use the InStr command to look for commas in the line-by-line streams of text. After you find a comma in a line, you look for the error message ID of 1004, which indicates a problem with an MSI installer package. By nesting a pair of If Then statements and using InStr, you easily filter only the desired messages. As a result, the size of the array is smaller and less memory is required. You haven’t implemented error handling here, which could easily be accomplished by using the Else command.

Do Until objTextFile.AtEndofStream strNextLine = objTextFile.ReadLine

If InStr (strNextLine, SearchString) > 0 Then If InStr ( strNextLine, ErrorString) > 0 Then

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

End If End If Loop

objTextFile.Close

Output Information

After the array arrTxtArray is created, each element of the array contains an entire event message from the event log. You could just print out each line, but a more func tional approach is to organize the data so that it is more comprehensible. To this end, you create a multidimensional array that holds specific elements of the event message.

You begin the Output information section by using For…Next to walk from the lower

boundary of the single dimensional array arrTxtArray to the upper boundary of arr-TxtArray. You then look for commas in each line contained in the elements incre mented by using the i counter. Once this is done, you build the multidimensional array and echo out only the elements that contain information you’re interested in seeing.

The script ends by echoing out an “all done” message.

For i = LBound(arrTxtArray) To UBound(arrTxtArray) If InStr (arrTxtArray(i), “,”) Then

newArray = Split (arrTxtArray(i), “,”) WScript.Echo “Date: “ & newArray(0) WScript.Echo “Time: “ & newArray(1)

WScript.Echo “Source: “ & newArray(2)& “ “& newArray(3) WScript.Echo “Server: “ & newArray(7)

WScript.Echo “Message1: “ & newArray(8) WScript.Echo “Message2: “ & newArray(9) WScript.Echo “Message3: “ & newArray(10) WScript.Echo “ “

End If Next

Quick Check

Q. What is the simplest way to break up a CSV data stream to populate an array?

A. You need to use the Split command and look for commas.

Q. What is the InStr command used for?

A. The InStr command is used to look for character combinations in a stream of text.

Q. What construct can be used to hold data records that are separated by commas?

A. A multidimensional array can be used to hold this type of data.