Hey, Scripting Guy! I have a log file in which new data is appended to the bottom of the file; that means the most recent entries are at the end of the file. I’d like to be able to read the file starting with the last line and then ending with the first line, but I can’t figure out how to do that.
— MB, Milwaukee, WI
Hey, MB. The FileSystemObject is extremely useful, but it also has its limitations; one of the major limitations is the fact that it can only read a file from top to bottom. Unlike, say, the Tail utility, you can’t ask the FileSystemObject to read a file from the bottom up. (Well, we suppose you can ask it, but it won’t do it for you.)
But that’s OK; as always seems to be the case with scripting, you can find a way to work around limitations like this. In this case, what we do is go ahead and read the file from top to bottom, beginning with line 1 and ending with line whatever. However, rather than immediately echoing these lines to the screen, we’ll store them in an array, with each line in the file representing one element in the array.
Why do we do that? Well, now we have an array that looks like this, replicating the way information is stored in the text file:
violet indigo blue green yellow orange red
Admittedly, all we seem to have done so far is re-invent the wheel. However, there’s one important difference between a text file and an array: it’s actually pretty easy to read an array from the bottom to the top. We’re going to tell our script to begin with the last item in the array (which we can determine using the Ubound function) and work backwards towards the first item in the array (Lbound).
In our sample array, we have 7 items in the array; the last item (Ubound) is the word red and the first item (Lbound) is the word violet. The first item in the array is given an index number of 0; thus violet has an index number of 0 and red has an index number of 6. Our script is going to start with item 6 and work backwards to item 0. How do we work backwards like that? We add the parameter Step -1, which essentially says, “Look at item 6 and do something with it. Then subtract 1 from the index number, which leaves 5. Look at item 5, and do something with it. Repeat this process until you’ve looked at all the items in the array.”
Here’s what the code looks like:
Dim arrFileLines() i = 0 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("C:\FSO\ScriptLog.txt", 1) Do Until objFile.AtEndOfStream Redim Preserve arrFileLines(i) arrFileLines(i) = objFile.ReadLine i = i + 1 Loop objFile.Close For l = Ubound(arrFileLines) to LBound(arrFileLines) Step -1 Wscript.Echo arrFileLines(l) Next
Slightly confusing if you haven’t worked much with arrays, but once you get the hang of it you’ll see how simple it really is.
Oh, and here’s what our bottom-to-top output looks like:
red orange yellow green blue indigo violet
For more information about working with arrays, see this portion of the Microsoft Windows 2000 Scripting Guide.