{"id":64063,"date":"2007-09-08T01:56:00","date_gmt":"2007-09-08T01:56:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/09\/08\/how-can-i-remove-any-line-in-a-text-file-that-contains-a-specified-string-value\/"},"modified":"2007-09-08T01:56:00","modified_gmt":"2007-09-08T01:56:00","slug":"how-can-i-remove-any-line-in-a-text-file-that-contains-a-specified-string-value","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-remove-any-line-in-a-text-file-that-contains-a-specified-string-value\/","title":{"rendered":"How Can I Remove Any Line in a Text File That Contains a Specified String Value?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> \n<P>Hey, Scripting Guy! How can I remove any line in a text file that contains the string <I>f0<\/I>?<BR><BR>&#8212; CJ<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\"><\/A> \n<P>Hey, CJ. Before we begin, we have a question for <I>you<\/I>: are you by any chance a serious player of online video games like EverQuest or World of Warcraft? Admittedly, none of the Scripting Guys play these games; we still find <A href=\"http:\/\/www.pong-story.com\/intro.htm\" target=\"_blank\"><B>Pong<\/B><\/A> to be a little over-stimulating for our tastes. However, we are absolutely fascinated by the underground economy that has sprung up around these \u201cmassively multiplayer online role-playing games.\u201d For example, suppose you start to play EverQuest and you suddenly realize, \u201cDang, I need a 77 monk <I>and<\/I> a 55 druid.\u201d What are you supposed to do <I>then<\/I>?<\/P>\n<P>Now, if you\u2019re stodgy, old-fashioned squares like the Scripting Guys, you\u2019d probably just continue to play the game and try to <I>earn<\/I> a 77 monk and a 55 druid. Apparently, though, actually playing the game they spend all their time playing is too much effort for a lot people; instead, they just jet over to <A href=\"http:\/\/www.ebay.com\/\" target=\"_blank\"><B>Ebay<\/B><\/A>, where you can buy video game characters for the low, low price of $115:<\/P>\n<TABLE class=\"dataTable\" id=\"EZD\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">70 monk with 720 aa&#8217;s, very good character. Has gloves of coalesced flame, bone staff of wickedness, fiery staff of zha, many other great items. I can show him in game, he is currently on the cazic thule server. There is also a 55 druid, 53 ranger, 35 paladin, 35 enchanter, 33 berserker. Account comes with 260k and a few items worth over 100k. Once payment is received i will give the station name, password, and secret question.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>And yes, that\u2019s $115 in real money, not some sort of virtual EverQuest money. <\/P>\n<P>Here\u2019s another ad we stumbled upon:<\/P>\n<TABLE class=\"dataTable\" id=\"EDE\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">This auction is for the time and energy spent to play this game and acquire the levels of the characters in the game. <I>Only a sheet of paper containing information is being sold<\/I>. [Italics added.] 75 Cleric on Luclin server. Original owner. Has many clickies that aren&#8217;t included in the magelo. AoN \/ Spectre Mask \/ DE Mask \/ Wood Elf Mask and many other great clickies. 13k hp \/ 14.6k mana UNBUFFED http:\/\/eq.magelo.com\/profile\/727280<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>The asking price for the \u201csheet of paper containing information?\u201d A mere $400. Also in real money.<\/P>\n<P>Let\u2019s face it: somehow, somewhere, the Scripting Guys became a bunch of old fogeys. $400 for a piece of paper? Not unless that piece of paper is a $1,000 bill.<\/P>\n<P>And even then we\u2019d have to think about it.<\/P>\n<P>As we noted, the underground economy surrounding online video games has become huge; in 2002, <A href=\"http:\/\/en.wikipedia.org\/wiki\/Everquest\" target=\"_blank\"><B>one researcher<\/B><\/A> estimated that EverQuest was the 77<SUP>th<\/SUP> richest \u201cnation\u201d on the face of the Earth. Admittedly, the Scripting Guys don\u2019t fully understand why people would pay huge amounts of real money just to acquire new characters or new equipment for a video game. But then again, it\u2019s not up to us to judge the motives behind the behaviors of other people; all we want to do is to get a piece of the action. Therefore, we have decided to offer everyone the deal of a lifetime: a Level 589 A5 script, <I>one that has never been included in the magelo<\/I>. The price for this script, which deletes all the lines in a text file that include the string <I>f0<\/I>? During this limited-time offering, you can get this script for just $3,985.<\/P>\n<P>Plus shipping and handling. <\/P>\n<P>Now, we know what you\u2019re thinking, you\u2019re thinking, \u201cWow, $3,985; that\u2019s a lot of money to pay for a Level 589 A5 EverQuest script, especially when you consider the fact that there\u2019s no such thing, and, even if there was, this script would be totally useless to anyone playing EverQuest.\u201d Granted, that <I>does<\/I> sound a bit pricey, even to the Scripting Guys. (Although, as we noted, this has <I>never<\/I> been included in the magelo. Ever.) But we have a feeling you\u2019ll change your mind after you learn how the script actually works.<\/P>\n<P>To begin with, let\u2019s pretend that you\u2019re a 55 druid and you have a text file (C:\\Scripts\\Test.txt) that looks like this:<\/P><PRE class=\"codeSample\">This line should stay.\nThis line (f0) should be deleted.\nThis line should also be deleted. (f0)\nThis line should not be deleted.\nThis line should remain.\nf0: This last line should be deleted.\n<\/PRE>\n<P>You\u2019re absolutely right about that: no 55 druid could afford to be caught dead with a text file like this one, not with all those lines of text that contain the string value <I>f0<\/I>. But how are you, a mere 55 druid, supposed to delete each and every line that contains that string value, and <I>only<\/I> those lines that contain that string value?<\/P>\n<P>Well, if you\u2019re smart, and if you have $3,985, you\u2019ll use a Level 589 A5 script like this one:<\/P><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 InStr(strLine, &#8220;f0&#8221;) = 0 Then\n        strNewContents = strNewContents &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)\nobjFile.Write strNewContents<\/p>\n<p>objFile.Close\n<\/PRE>\n<P>And yes, we\u2019ll explain how this script works; for $3,985, that\u2019s the least we can do. As you can see, we start out by defining a pair of constants, ForReading and ForWriting; we\u2019ll need these two constants when we open the text file. (For better or worse, we have to open the file twice: once to read the current contents of the file into memory, and a second time to write the modified contents back to the file.) After defining our two constants we create an instance of the <B>Scripting.FileSystemObject<\/B> object, then use the following line of code to open the file C:\\Scripts\\Test.txt for reading:<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)\n<\/PRE>\n<P>You\u2019re right: that probably <I>is<\/I> worth $3,985 right there. But we\u2019re not done yet; far from it. Instead, once our file is open for reading we execute this block of code:<\/P><PRE class=\"codeSample\">Do Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\n    If InStr(strLine, &#8220;f0&#8221;) = 0 Then\n        strNewContents = strNewContents &amp; strLine &amp; vbCrLf\n    End If\nLoop\n<\/PRE>\n<P>Good question: what <I>are<\/I> we doing here? (No need to apologize; we wouldn\u2019t <I>expect<\/I> a 55 druid to know what that block of code is for.) For starters, what we\u2019re doing here is setting up a Do Until loop designed to run until we reach the end of the file. (Or, for all you 33 berserkers out there, until the file\u2019s <B>AtEndOfStream<\/B> property is True.) Inside this loop we\u2019re going to read the file line-by-line; that\u2019s what this line of code (and the <B>ReadLine<\/B> method) is for:<\/P><PRE class=\"codeSample\">strLine = objFile.ReadLine\n<\/PRE>\n<P>As you can probably figure out for yourself, the first time through the loop we\u2019re going to read the first line in the text file and store that value in the variable strLine. (In case you\u2019ve forgotten, the first line in the text file is this: <B>This line should stay<\/B>.)<\/P>\n<P>What we need to do now is determine whether or not the string value <I>f0<\/I> appears anywhere within that line of text. <I>How<\/I> do we do that? Why, by using VBScript\u2019s <B>InStr<\/B> function, of course:<\/P><PRE class=\"codeSample\">If InStr(strLine, &#8220;f0&#8221;) = 0 Then\n<\/PRE>\n<P>The InStr function looks at a string value (like the variable strLine) and reports back the character positions where the target text (f0) is found. For example, if strLine was equal to <I>123f0<\/I>, InStr would report back the value 4. Why? Because the target text begins in the fourth character position:<\/P>\n<TABLE class=\"dataTable\" id=\"EMH\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">Position 1<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">Position 2<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">Position 3<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">Position 4<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">Position 5<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">1<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">2<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">3<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\"><B>f<\/B><\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">0<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>And what if the target text <I>can\u2019t<\/I> be found, as is the case with our first line of text? No problem; in that case, InStr returns a 0. <\/P>\n<P>The fact that InStr returns a 0 if the target text can\u2019t be found turns out to be pretty useful, at least for all us 55 druids. If InStr returns anything <I>but<\/I> a 0 that means that the target text was found somewhere in the string strValue; in turn, that means that this is a line of text that we need to discard. Because of that, we don\u2019t do anything if we get back a value other than 0; we just ignore that line of text altogether. However, if we <I>do<\/I> get back a 0 (meaning that the target text could <I>not<\/I> be found) then we execute this line of code:<\/P><PRE class=\"codeSample\">strNewContents = strNewContents &amp; strLine &amp; vbCrLf\n<\/PRE>\n<P>Again, this should be pretty straightforward: all we\u2019re doing here is assigning a value to a variable named strNewContents, a value made up of the following:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The current value of strNewContents (the current value, the first time through the loop, being an empty string).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The line of text we just read in from the text file (represented by the variable strLine).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>A carriage return-linefeed (represented by the VBScript constant vbCrLf).<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>And then we loop around and repeat the process with the next line in the text file.<\/P>\n<P>By the time we\u2019ve reached the end of the file (OK, OK: the end of the <I>stream<\/I>) the variable strNewContents will be equal to the following, which just happens to be the contents of the text file minus any lines that contain the string f0:<\/P><PRE class=\"codeSample\">This line should stay.\nThis line should not be deleted.\nThis line should remain.\n<\/PRE>\n<P>That\u2019s great but, for the moment anyway, the text file itself remains unchanged. But we can fix that. After closing the file (text files can be opened for reading <I>or<\/I> for writing, but not for both, at least not at the same time) we then immediately reopen the thing, this time for writing:<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForWriting)\n<\/PRE>\n<P>At that point all we have to do is call the <B>Write<\/B> method and write the modified contents (the value of strNewContents) to the text file:<\/P><PRE class=\"codeSample\">objFile.Write strNewContents\n<\/PRE>\n<P>After that we close the text file one last time and we\u2019re done.<\/P>\n<P>That should do it, CJ; just send us a check for $3,985 and we\u2019ll call it good. Oh, and in case you\u2019re wondering, the answer is no, at this time the Scripting Guys do <I>not<\/I> offer tours of virtual worlds like EverQuest. <\/P>\n<P>But don\u2019t fret; amazing enough, there are <A href=\"http:\/\/www.synthravels.com\/\" target=\"_blank\"><B>travel agencies<\/B><\/A> that <I>do<\/I> offer guided tours of virtual worlds like EverQuest.<\/P>\n<P>Maybe we Scripting Guys need to give Pong another chance. We can\u2019t afford to get any more fogeyish than we already are.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I remove any line in a text file that contains the string f0?&#8212; CJ Hey, CJ. Before we begin, we have a question for you: are you by any chance a serious player of online video games like EverQuest or World of Warcraft? Admittedly, none of the Scripting Guys play [&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-64063","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! How can I remove any line in a text file that contains the string f0?&#8212; CJ Hey, CJ. Before we begin, we have a question for you: are you by any chance a serious player of online video games like EverQuest or World of Warcraft? Admittedly, none of the Scripting Guys play [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64063","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=64063"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64063\/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=64063"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64063"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}