{"id":63853,"date":"2007-10-08T22:20:00","date_gmt":"2007-10-08T22:20:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/10\/08\/hey-scripting-guy-how-can-i-remove-unwanted-tabs-from-a-text-file\/"},"modified":"2007-10-08T22:20:00","modified_gmt":"2007-10-08T22:20:00","slug":"hey-scripting-guy-how-can-i-remove-unwanted-tabs-from-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-remove-unwanted-tabs-from-a-text-file\/","title":{"rendered":"Hey, Scripting Guy! How Can I Remove Unwanted Tabs From a Text File?"},"content":{"rendered":"<p><H2><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\"> <\/H2>\n<P>Hey, scripting Guy! I have about 5,000 text files that have unwanted tabs at the end of each line. How can I write a script that removes these unwanted tabs?<BR><BR>&#8212; TT<\/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<TABLE id=\"E1C\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. If this looks \u2013 and sounds \u2013 a little different than the typical <I>Hey, Scripting Guy!<\/I> column, well, there\u2019s a good reason for that: that\u2019s because it <I>is<\/I> a little different than the typical <I>Hey, Scripting Guy!<\/I> column. The original column for October 8, 2007 had to be taken down because it referred to a third-party company (flattering references, but references nonetheless). We were given the option of \u201creworking\u201d the article, but there was really no way to do that without rewriting the entire column. Therefore, we decided to just post the code and the explanation of the code and call it good. We hope you enjoy this column as much as we\u2019ve enjoyed bringing it to you!<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV><PRE class=\"codeSample\">Const ForReading = 1\nConst ForWriting = 2<\/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\n    If Right(strLine, 1) = Chr(9) Then\n        intLength = Len(strLine)\n        strLine = Left(strLine, intLength &#8211; 1)\n        strContents = strContents &amp; strLine &amp; vbCrLf\n    End If\nLoop<\/p>\n<p>objFile.Close<\/p>\n<p>Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForWriting)<\/p>\n<p>objFile.Write strContents<\/p>\n<p>objFile.Close\n<\/PRE>\n<P>We start this script off the same way we start off many of our text file scripts: by defining a pair of constants (ForReading and ForWriting) that will be used when we go to open our text file. After the constants are defined, we create an instance of the <B>Scripting.FileSystemObject<\/B>, then use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.txt for reading:<\/P><PRE class=\"codeSample\">Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)\n<\/PRE>\n<P>Once the file is open we set up a Do Until loop that runs until the file\u2019s <B>AtEndOfStream<\/B> property is True. (Which is just a fancy way of saying that we\u2019ll keep looping until we\u2019ve read the entire file.) Inside that loop, we use the <B>ReadLine<\/B> method to read the first line in the file, storing the value in a variable named strLine:<\/P><PRE class=\"codeSample\">strLine = objFile.ReadLine\n<\/PRE>\n<P>That brings us to this line of code:<\/P><PRE class=\"codeSample\">If Right(strLine, 1) = Chr(9) Then\n<\/PRE>\n<P>Although TT said that all the lines in his text files end in an unwanted tab we decided to use this line of code to verify that a given line ends with a tab character. How do we do that? By using the <B>Right<\/B> function to take a peek at the very last character in the string. If this character has an ASCII value of 9 that can mean only one thing: it\u2019s a tab character. And that means that it has to go.<\/P>\n<P>OK, so then how do we remove that unwanted tab from the end of the string? Well, to begin with, we use the <B>Len<\/B> function to determine the total number of characters in the string, storing that value in a variable named intLength. We then use the <B>Left<\/B> function to grab all the characters <I>except<\/I> the very last one. (That\u2019s what the construction <B>intLength \u2013 1<\/B> is for.) In other words, suppose our string was this: <B>cat<\/B>. The length of the string (total characters) is 3; the length minus 1 is, um, hold on a second \u2026 2. Therefore, if we start at the beginning of the string and take the first two characters, that means our new string is equal to this: <B>ca<\/B>.<\/P>\n<P>Just in case there was any confusion as to what we were doing.<\/P>\n<P>From there we use this line of code to add the modified string value (plus a carriage return-linefeed character) to a variable named strContents:<\/P><PRE class=\"codeSample\">strContents = strContents &amp; strLine &amp; vbCrLf\n<\/PRE>\n<P>And then we loop around and repeat this process with the next line in the text file, removing the unwanted tab and then tacking that modified line onto the end of strContents. And so on and so on and so on.<\/P>\n<P>By the time we exit the loop we will have constructed a brand-new version of our file in memory, a version where all the unwanted tabs have been removed. In order to write this new version back to the actual file itself (C:\\Scripts\\Test.txt) we first need to close the file, then use the OpenTextFile method to reopen it, this time for writing:<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForWriting)\n<\/PRE>\n<P>Once the file is open we use the <B>Write<\/B> method to write the new version of the file to Test.txt. As soon as that\u2019s done we call the <B>Close<\/B> method to close the file a final time and then we call it a day.<\/P>\n<P>Good question: why didn\u2019t we just use the Replace function to replace all the tabs? Well, we could have, except for one thing: it\u2019s possible that there are other tabs in the file, tabs that <I>shouldn\u2019t<\/I> be removed. The Replace functions would remove <I>all<\/I> tabs; the approach we showed you only removes tabs found at the end of a line.<\/P>\n<P>As long as we\u2019re on the subject, it\u2019s also possible that some lines could have more than one unwanted tab tacked onto the end. Is it possible to remove multiple tabs at the end of a line? You bet it is. Here\u2019s a modified Do Loop that features a <I>second<\/I> Do Until loop; in that second loop, we check the last character in the string and, if it\u2019s a tab, we remove it. We then check the last character in our modified string; if that happens to be a tab we remove it as well. This continues until we\u2019ve removed all the tab characters found at the end of the line.<\/P>\n<P>Here\u2019s the modified code:<\/P><PRE class=\"codeSample\">Do Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\n    Do Until i = 100\n        If Right(strLine, 1) = Chr(9) Then\n            intLength = Len(strLine)\n            strLine = Left(strLine, intLength &#8211; 1)\n        Else\n            Exit Do\n        End If\n    Loop\n    strContents = strContents &amp; strLine &amp; vbCrLf\nLoop\n<\/PRE><BR><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, scripting Guy! I have about 5,000 text files that have unwanted tabs at the end of each line. How can I write a script that removes these unwanted tabs?&#8212; TT Note. If this looks \u2013 and sounds \u2013 a little different than the typical Hey, Scripting Guy! column, well, there\u2019s a good reason for [&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":[3,4,14,5],"class_list":["post-63853","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, scripting Guy! I have about 5,000 text files that have unwanted tabs at the end of each line. How can I write a script that removes these unwanted tabs?&#8212; TT Note. If this looks \u2013 and sounds \u2013 a little different than the typical Hey, Scripting Guy! column, well, there\u2019s a good reason for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63853","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=63853"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63853\/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=63853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}