{"id":67833,"date":"2006-03-03T16:53:00","date_gmt":"2006-03-03T16:53:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/03\/03\/how-can-i-read-just-the-last-line-of-a-text-file\/"},"modified":"2006-03-03T16:53:00","modified_gmt":"2006-03-03T16:53:00","slug":"how-can-i-read-just-the-last-line-of-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-read-just-the-last-line-of-a-text-file\/","title":{"rendered":"How Can I Read Just the Last Line of a Text file?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I read just the last line of a text file?<BR><BR>&#8212; BM<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, BM. You know, if you\u2019ve ever wondered how <I>Hey, Scripting Guy!<\/I> differs from other daily columns (like, say, <I>Dear Abby<\/I>), well, here\u2019s one way. Suppose someone writes Dear Abby and says this:<\/P>\n<P>Dear Abby:<BR>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?<BR>Desperate in Dayton<\/P>\n<P>Most likely Dear Abby would never give Desperate an answer like this:<\/P>\n<P>Dear Desperate:<BR>Well, you can\u2019t. Sorry.<\/P>\n<P>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:<\/P>\n<P>Dear BM:<BR>Well, you can\u2019t. Sorry.<\/P>\n<P>But wait, don\u2019t go yet. It\u2019s true that Dear Abby would never say, \u201cYou know, Desperate, I can\u2019t help you become happy. But here\u2019s a workaround that will make it <I>look<\/I> like you\u2019re happy.\u201d The Scripting Guys, however, have no such qualms. In other words, we can\u2019t give you a script that reads just the last line of a text file. But here\u2019s a script that will make it <I>look<\/I> like you read just the last line of a text file:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)<\/p>\n<p>Do Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\nLoop<\/p>\n<p>objFile.Close<\/p>\n<p>Wscript.Echo strLine\n<\/PRE>\n<P>The problem we\u2019ve run into here is that the FileSystemObject (the scripting object used to work with text files) knows only one direction: forward. It <I>has<\/I> to start at the beginning of a file, and it can only continue on towards the end of that file. You can\u2019t specify an alternate starting location and you can\u2019t read backwards (from the end to the beginning). In fact, you can\u2019t even re-read a file: if you reach the end there\u2019s no way to start all over except by closing and re-opening the file. That\u2019s why workarounds are pretty much par for the course when it comes to text files.<\/P>\n<P>The workaround here is that we actually <I>do<\/I> read the entire script from beginning to end. However, we keep track of only the very last line we\u2019ve read. When we reach the end of the file, we\u2019ll 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 <I>look<\/I> like we read only the last line (especially because, if nothing else, the FileSystemObject is pretty fast). We didn\u2019t &#8211; we actually read the entire file &#8211; but no one will ever know. It\u2019ll be our little secret.<\/P>\n<P>As for the code itself, we begin by defining a constant named ForReading and setting the value to 1; we\u2019ll use this constant to tell the FileSystemObject that we want to open a file for reading. We then create an instance of the <B>Scripting.FileSystemObject<\/B>, and use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.txt. That brings us to this block of code:<\/P><PRE class=\"codeSample\">Do Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\nLoop\n<\/PRE>\n<P>All we\u2019re doing here is reading the file, line by line, until we reach the end (that is, until we\u2019re 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:<\/P><PRE class=\"codeSample\">A\nB\nC\n<\/PRE>\n<P>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\u2019ve 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 &#8211; and report back &#8211; the value of the last line in the file.<\/P>\n<P>Yes, very sneaky.<\/P>\n<P>Admittedly, there\u2019s 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\u2019s what it <I>should<\/I> do: after all, the last line in the file <I>is<\/I> 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\u2019re probably <I>really<\/I> interested in is the last non-blank line in the file. Here\u2019s a modified version of the script that uses the <B>Len<\/B> function to check the length of each line that\u2019s read in. If the length is equal to 0, that means it\u2019s a blank line, and the value is <I>not<\/I> stored in the variable strLine:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)<\/p>\n<p>Do Until objFile.AtEndOfStream\n    strNextLine = objFile.ReadLine\n    If Len(strNextLine) &gt; 0 Then\n        strLine = strNextLine\n    End If\nLoop<\/p>\n<p>objFile.Close<\/p>\n<p>Wscript.Echo strLine\n<\/PRE>\n<P>Eat your heart out, Dear Abby!<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I read just the last line of a text file?&#8212; BM Hey, BM. You know, if you\u2019ve ever wondered how Hey, Scripting Guy! differs from other daily columns (like, say, Dear Abby), well, here\u2019s one way. Suppose someone writes Dear Abby and says this: Dear Abby:My life is all messed [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[40,3,4,14,5],"class_list":["post-67833","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-filesystemobject","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I read just the last line of a text file?&#8212; BM Hey, BM. You know, if you\u2019ve ever wondered how Hey, Scripting Guy! differs from other daily columns (like, say, Dear Abby), well, here\u2019s one way. Suppose someone writes Dear Abby and says this: Dear Abby:My life is all messed [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67833","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=67833"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67833\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=67833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}