How Can I Read Just a Single, Specified Line from a Text File?
Hey, Scripting Guy! How can I read only a specific line in a text file? For example, how can I write a script that reads only line 16 in a text file and then stores the value of that line in a variable?
Hey, DL. You know we haven’t answered a question about text files in awhile, and that’s not something we should brag about; after all, it sometimes seems like every other question we get has to do with reading from and writing to text files. People always ask if we’ve ever met Bill Gates; the truth is we always try to avoid Bill Gates, because we’re afraid he’ll ask us questions about text files.
Of course, the reason we get so many questions about text files is the fact that the scripting technologies built into Windows don’t have very sophisticated text handling capabilities. Take this question, for example. You might think that WSH or VBScript or some scripting object would have a method in which you could say, “Hey, go read line 16 and only line 16 of this file.” No such luck. The FileSystemObject – which provides most of the text-handling capabilities available to scripters – can only start with line 1 of a file and then works its way down. There’s no way to quickly jump to a specified line.
Now, that doesn’t mean we can’t store just the value of line 16 in a variable; it just means we have to use a somewhat less-than-elegant approach. For the sake of brevity, let’s consider a simple text file with five lines:
1 2 3 This is line no. 4 in the text file. 5
We want to store the contents of line 4 – and just the contents of line 4 – in a variable. We can’t jump to line 4 directly, but we can achieve the desired result by using a script like this:
Const ForReading = 1
Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objTextFile = objFSO.OpenTextFile(“mylogfile.log”, ForReading)
For i = 1 to 3 objTextFile.ReadLine Next
strLine = objTextFile.ReadLine Wscript.Echo strLine
So what’s going on here? Well, we begin by creating an instance of the FileSystemObject and opening the file Mylogfile.log for reading. We then create a For Next loop that loops from 1 to 3. Inside that loop, we use the ReadLine method to read the current line in the text file.
Why? Well, remember, all we’re really interested in is line 4, but the FileSystemObject won’t let us go directly to line 4; instead, we have to get through lines 1, 2, and 3 first. That’s exactly what this block of code does. The first time through the loop, it calls the ReadLine method; this reads the first line in the text file (although we don’t do anything with the information we read), and then automatically drops us down to the next line in the file (line 2). The second time through, we read line 2, and drop down to line 3. The third time through – that’s right, we read line 3, and then drop down to line 4, the line we’re interested it.
At this point, we’re done with our loop. We call the ReadLine method again, only this time we store the contents of that line in the variable strLine. That’s what we do here:
strLine = objTextFile.ReadLine
For the purposes of our demonstration script, we then echo the value of strLine and close the text file. We weren’t able to use any nifty shortcuts, but we achieved our goal: we managed to get the value of line 4 into the variable strLine.
Like we said, not very elegant, but it works. And it works reasonably fast, too. For example, create a sample log file with 10,000 lines, and modify the script so it stores just the value of line 9999 in a variable. (How would you do that? Change the For Next loop so that it loops from 1 to 9998.) Then echo the value of line 9999. If you try this, you’ll see that – elegance aside – the whole process only takes a second or so. Beauty is in the eye of the beholder, and we find any script that takes only a second or two to complete to be very beautiful indeed.