How Can I Read Just the Last Line of a Text file?

How Can I Read Just the Last Line of a Text file?

  • Comments 1
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I read just the last line of a text file?

-- BM

SpacerHey, Scripting Guy! AnswerScript Center

Hey, BM. You know, if you’ve ever wondered how Hey, Scripting Guy! differs from other daily columns (like, say, Dear Abby), well, here’s one way. Suppose someone writes Dear Abby and says this:

Dear Abby:
My life is all messed up and I need to do something about it. How can I turn my life around and be happy again?
Desperate in Dayton

Most likely Dear Abby would never give Desperate an answer like this:

Dear Desperate:
Well, you can’t. Sorry.

So how do you think the Scripting Guys will answer your question about reading just the last line of a text file? You got it:

Dear BM:
Well, you can’t. Sorry.

But wait, don’t go yet. It’s true that Dear Abby would never say, “You know, Desperate, I can’t help you become happy. But here’s a workaround that will make it look like you’re happy.” The Scripting Guys, however, have no such qualms. In other words, we can’t give you a script that reads just the last line of a text file. But here’s a script that will make it look like you read just the last line of a text file:

Const ForReading = 1

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)

Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
Loop

objFile.Close

Wscript.Echo strLine

The problem we’ve run into here is that the FileSystemObject (the scripting object used to work with text files) knows only one direction: forward. It has to start at the beginning of a file, and it can only continue on towards the end of that file. You can’t specify an alternate starting location and you can’t read backwards (from the end to the beginning). In fact, you can’t even re-read a file: if you reach the end there’s no way to start all over except by closing and re-opening the file. That’s why workarounds are pretty much par for the course when it comes to text files.

The workaround here is that we actually do read the entire script from beginning to end. However, we keep track of only the very last line we’ve read. When we reach the end of the file, we’ll have a variable that contains the value of the last line read; that will also be the last line in the file. When we echo back the value of that variable it will look like we read only the last line (especially because, if nothing else, the FileSystemObject is pretty fast). We didn’t - we actually read the entire file - but no one will ever know. It’ll be our little secret.

As for the code itself, we begin by defining a constant named ForReading and setting the value to 1; we’ll use this constant to tell the FileSystemObject that we want to open a file for reading. We then create an instance of the Scripting.FileSystemObject, and use the OpenTextFile method to open the file C:\Scripts\Test.txt. That brings us to this block of code:

Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
Loop

All we’re doing here is reading the file, line by line, until we reach the end (that is, until we’re at the end of the file stream). Each time we read in a line we replace the value of the variable strLine with the text we just read. For example, suppose our text file consists of three lines:

A
B
C

Inside our loop we read in line 1, and thus assign the value A to strLine. We loop around and read the second line, meaning the value B gets assigned to strLine. We loop around again and assign the value C to strLine. Because we’ve reached the end of the file strLine retains the value C, which just happens to be the last line in the file. We then close the file and echo the value of strLine. As far as anyone knows, all we did was read - and report back - the value of the last line in the file.

Yes, very sneaky.

Admittedly, there’s one potential problem with this script. Suppose you have a file that has several blank lines tacked on to the end. Our script will dutifully report back nothing (a blank value) as the last line in the text file. That’s what it should do: after all, the last line in the file is blank. But suppose this is a log file of some type and, for whatever reason, the application that creates this log always throws a few blank lines onto the end of the file. In that case what you’re probably really interested in is the last non-blank line in the file. Here’s a modified version of the script that uses the Len function to check the length of each line that’s read in. If the length is equal to 0, that means it’s a blank line, and the value is not stored in the variable strLine:

Const ForReading = 1

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)

Do Until objFile.AtEndOfStream
    strNextLine = objFile.ReadLine
    If Len(strNextLine) > 0 Then
        strLine = strNextLine
    End If
Loop

objFile.Close

Wscript.Echo strLine

Eat your heart out, Dear Abby!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • ReadAll and split to array working faster