Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I count the number of times the word Failure appears in a log file? There’s one catch, though: the log file simply writes its events one after another, creating one big, giant line of text.

-- FS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, FS. According to the rest of your email, your log file looks something like this:

Failure 2/7/2006 8:25 AM Failure 2/7/2006 9:45 AM Success 
2/7/2006 3:10 PM Failure 2/8/2006 9:15 AM Success 2/7/2006 3:01 PM

As you also noted, your first thought was to use the InStr function to see if the word Failure appears anywhere in each line of the log file; you could then keep a running tally of the number of times you found the word, a technique remarkably similar to the one we demonstrated in yesterday’s column. That was a good idea, but, as you discovered, there was one major flaw in the plan: technically your log file has only one line in it. Consequently, your script always reported that it found one instance of the word Failure, regardless of how many instances actually existed. “But I’m stuck,” you wrote, “because there’s no way to break this single line into multiple lines.”

Oh ye of little faith. Try this on for size:

Const ForReading = 1

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\scripts\test.log", ForReading)
strContents = objFile.ReadAll
objFile.Close

i = 0

arrLines = Split(strContents, " ")

For Each strLine in arrLines
    If InStr(strLine, "Failure") Then
        i = i + 1
    End If
Next

Wscript.Echo "Number of failures: " & i

Now, admittedly, there are a couple other ways we could have solved this problem. We went with this approach because it piggybacked nicely on your original thought, and because we thought it would be fairly easy for everyone to understand. We mention this simply in case anyone is reading this and thinking, “Man, that’s not how I would have solved this.” That’s fine: this isn’t the answer. It’s just an answer.

OK, so what about the script itself? Well, we begin by defining a constant named ForReading; we’ll use this constant later on when we open our log file. We then create an instance of the Scripting.FileSystemObject and use the OpenTextFile method to open the file C:\Scripts\Test.log. With the file open, we use the ReadAll method to read the entire contents of the file into a variable named strContents, and then we close Test.log.

Got that? Next we assign the value 0 to a counter variable named i; we’ll use i to keep a running tally of each instance of the word Failure that we run into. And then we have this line of code:

arrLines = Split(strContents, " ")

Remember how you said that you were stuck because your log file was all one big long line? Well, basically what we’re doing here is dividing your log file (or at least the version of it stored in the variable strContents) into a whole bunch of little lines. In your log file individual words are separated by a blank space. In this line of code, we use the Split function to “split” the value of strContents into an array; by splitting on the blank space (that is, by creating a new item in the array each time we encounter a blank space) we end up with an array that starts out like this:

Failure 
2/7/2006 
8:25 
AM 
Failure 
2/7/2006 
9:45 
AM 
Success

Sure, it looks funny, but now we can set up a For Each loop to run through each item in the array; more important, we can also use the InStr method to see if the word Failure can be found in any of those lines. If it can, we then increment the value of our counter variable i. All of that takes place within this block of code:

For Each strLine in arrLines
    If InStr(strLine, "Failure") Then
        i = i + 1
    End If
Next

After we run through our For Each loop all we have to do is echo back our failures and we’re done.

Well, check that: all we have to do is echo back the number of failures found in the log file. Your script would likely time out long before it could finish echoing back all of our failures. (Although we still think Scripting with Celebrities would be far more entertaining than watching someone dance or ice skate with celebrities.)