{"id":55813,"date":"2008-04-10T01:01:00","date_gmt":"2008-04-10T01:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/04\/10\/hey-scripting-guy-how-can-i-conditionally-add-lines-to-a-text-file\/"},"modified":"2008-04-10T01:01:00","modified_gmt":"2008-04-10T01:01:00","slug":"hey-scripting-guy-how-can-i-conditionally-add-lines-to-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-conditionally-add-lines-to-a-text-file\/","title":{"rendered":"Hey, Scripting Guy! How Can I Conditionally Add Lines to a Text File?"},"content":{"rendered":"<p><img decoding=\"async\" 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\" \/> <\/p>\n<p>Hey, Scripting Guy! I need a script that can read a file and, based on the contents, insert some additional lines of text into that file. Can you help me with that?<br \/>&#8212; JS<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" 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 decoding=\"async\" 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> <\/p>\n<p>Hey, JS. We\u2019re sure that most of you have heard by now that Microsoft has made an offer to buy <a href=\"http:\/\/www.yahoo.com\/\" target=\"_blank\"><b>Yahoo<\/b><b>!<\/b><\/a>, an offer currently valued at around $42 billion. (Because the offer is based, in part, on stock prices the value of the deal tends to fluctuate on a daily basis.) So far, however, Yahoo! has held out for an even <i>better<\/i> deal, noting in a letter to Microsoft CEO Steve Ballmer, \u201cWe are steadfast in our commitment to choosing a path that maximizes stockholder value and we will not allow you or anyone else to acquire the company for anything less than its full value.\u201d <\/p>\n<p>Because, obviously, a company that doesn\u2019t actually <i>make<\/i> anything (including money) is worth way more than $42 billion.<\/p>\n<table class=\"dataTable\" id=\"ELD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Ed<\/b><b>itor\u2019s Note:<\/b> Yes, it appears the Scripting Guy who writes this column is trying to get himself (and the Scripting Editor) into trouble once again. Last time the Scripting Guy who writes this column even <i>mentioned<\/i> another popular Web site that article was removed immediately. Once people see what\u2019s in here, well \u2026 read quickly and assume you\u2019re one of the few who will actually see what\u2019s in here.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Microsoft has yet to respond to this latest salvo from Yahoo!, which can mean only one thing: it\u2019s time for the Scripting Guys to step in. Obviously money is not important to the folks at Yahoo!; if it was, they would take the $42 billion and run. Instead, they must be holding out for something better and more meaningful than money. Which is why the Scripting Guys have decided to enter the negotiations: if Yahoo! will give us the entire company, in turn, we will give every Yahoo! shareholder their very own <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/bobbles.mspx\"><b>Dr. Scripto bobblehead doll<\/b><\/a>. That\u2019s something that even $42 billion can\u2019t buy.<\/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\"><b>Note<\/b>. Well, OK, if you want to get technical, $42 billion would actually buy you over 4 <i>billion<\/i> Dr. Scripto bobblehead dolls. But let\u2019s not tell anyone at Yahoo! that, OK?<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>At any rate, if anyone from the Yahoo! board of directors is reading this, drop us a line and let us know what you think. We should note, however, that this offer <i>is<\/i> non-negotiable. That\u2019s not because we aren\u2019t willing to negotiate, it\u2019s just because we don\u2019t have anything other than a few bobbleheads we can negotiate with. The Scripting Editor says she\u2019s willing to toss her Lexus into the deal, but it would be up to you guys to figure out who got to drive it, and when.<\/p>\n<table class=\"dataTable\" id=\"EWE\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p><b>Note<\/b>. OK, so the Scripting Editor didn\u2019t actually <i>say<\/i> she would toss her Lexus into the deal, in part because we didn\u2019t actually ask her. But the Scripting Editor\u2019s a team player, and we don\u2019t expect to have any problems with her.<\/p>\n<p>Well, not unless she finds out about this.<\/p>\n<p><b>Ed<\/b><b>itor\u2019s Note:<\/b> The Scripting Editor is going to need her Lexus so she has a place to live after this article is discovered.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Of course, many of you are probably concerned about this impending deal. You\u2019re probably thinking, \u201cGee, if the Scripting Guys take over Yahoo! they\u2019ll be rich and powerful. When that happens they aren\u2019t going to want to spend their time writing about system administration scripting.\u201d Well you know what? You\u2019re absolutely right about that; we\u2019ll be on the beach in Tahiti before the ink dries on the contract. But seeing as how we don\u2019t actually own Yahoo! (at least not yet) we\u2019ll go ahead and answer JS\u2019 question:<\/p>\n<pre class=\"codeSample\">Const ForReading = 1\nConst ForWriting = 2\n\nSet objFSO = CreateObject(\"Scripting.FileSystemObject\")\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n\nDo Until objFile.AtEndOfStream\n    strLine1 = objFile.ReadLine\n    If InStr(strLine1, \"Medical\") Then\n        strDuplicateLine = strLine1\n        strDuplicateLine = Replace(strDuplicateLine, \"Medical\", \"Dental\")\n   End If\n    strLine2 = objFile.ReadLine\n    strLine3 = objFile.ReadLine\n    strText = strText &amp; strLine1 &amp; vbCrLf &amp; strLine2 &amp; vbCrLf &amp; strLine3 &amp; vbCrLf\n    \n    If strDuplicateLine &lt;&gt; \"\" Then\n        strText = strText &amp; strDuplicateLine &amp; vbCrLf &amp; strLine2 &amp; vbCrLf &amp; strLine3 &amp; vbCrLf\n    End If\n\n    strDuplicateLine = \"\"\nLoop\n\nobjFile.Close\n\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForWriting)\nobjFile.Write strText\nobjFile.Close\n<\/pre>\n<p>Before we launch into a discussion of how this script works, let\u2019s take a peek at the text we\u2019re working with. JS has a text file that looks a little something like this:<\/p>\n<pre class=\"codeSample\">Ken Myer, Medical, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12345\nPilar Ackerman, None, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12346\n<\/pre>\n<p>As you can see, every three lines in the file represent a record for a particular person: line 1 (which we\u2019ll get back to in a second) includes the person\u2019s name; line 2 includes a date; and line 3 includes a reference number. If line 1 also includes the word <i>Medical<\/i> we want to duplicate this record, but with one exception: in the duplicate record we want to substitute the word <i>Dental<\/i> for the word <i>Medical<\/i>. In other words, if our script does what it\u2019s supposed to do then Ken Myer should end up with the following two records:<\/p>\n<pre class=\"codeSample\">Ken Myer, Medical, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12345\nKen Myer, Dental, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12345\n<\/pre>\n<p>See how that works? And what happens to Pilar Ackerman? Nothing. Because her record does <i>not<\/i> contain the word <i>Medical<\/i> her information remains exactly as-is:<\/p>\n<pre class=\"codeSample\">Pilar Ackerman, None, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12346\n<\/pre>\n<p>Got all that? Good. Now let\u2019s see if we can figure out how to get our script to accomplish this task.<\/p>\n<p>To begin with, we define a pair of constants \u2013 ForReading and ForWriting \u2013 that we\u2019ll need when we open the text file. Speaking of which, that\u2019s the very next thing we do: we use these two lines of code to create an instance of the <b>Scripting.FileSystemObject<\/b> and open the file C:\\Scripts\\Test.txt for reading:<\/p>\n<pre class=\"codeSample\">Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n<\/pre>\n<p>Once the text file is open we need to start examining the contents of that file line-by-line. To that end, we set up a Do Until loop designed to run until we\u2019ve read every line in the file (or, to be a bit more technical, to run until the file\u2019s <b>AtEndOfStream<\/b> property is True):<\/p>\n<pre class=\"codeSample\">Do Until objFile.AtEndOfStream\n<\/pre>\n<p>Inside the loop, the first thing we do is use the <b>ReadLine<\/b> method to read the first line in the file and store it in a variable named strLine1:<\/p>\n<pre class=\"codeSample\">strLine1 = objFile.ReadLine\n<\/pre>\n<p>From there we use the <b>InStr<\/b> function to determine whether or not the word <i>Medical<\/i> appears anywhere in the value of strLine1:<\/p>\n<pre class=\"codeSample\">If InStr(strLine1, \"Medical\") Then\n<\/pre>\n<p>Now, what happens if the line <i>doesn\u2019t<\/i> contain the word <i>Medical<\/i>? To be honest, nothing happens; because we didn\u2019t find the word <i>Medical<\/i> there\u2019s nothing special we need to do with this record. But it\u2019s a different story if we <i>do<\/i> find the word <i>Medical<\/i>. In that case, we\u2019re going to run these two lines of code:<\/p>\n<pre class=\"codeSample\">strDuplicateLine = strLine1\n        strDuplicateLine = Replace(strDuplicateLine, \"Medical\", \"Dental\")\n<\/pre>\n<p>What are we doing here? Well, as you can see, we\u2019re really not doing all that much. In line 1 we assign the value of strLine1 to a variable named strDuplicateLine; in effect, we\u2019re making a virtual copy of the first line in the text file. In line 2 we take the variable strDuplicateLine and replace the word <i>Medical<\/i> with the word <i>Dental<\/i>. Once we\u2019ve done that the variable strLine will be equal to this:<\/p>\n<pre class=\"codeSample\">Ken Myer, Medical, 1\/1\/1980\n<\/pre>\n<p>Meanwhile, the variable strDuplicateLine will be equal to this:<\/p>\n<pre class=\"codeSample\">Ken Myer, Dental, 1\/1\/1980\n<\/pre>\n<p>And yes, that <i>is<\/i> good: we now have the first line for Ken Myer\u2019s Medical record <i>and<\/i> the first line for his Dental record.<\/p>\n<p>That brings us to these two lines of code:<\/p>\n<pre class=\"codeSample\">strLine2 = objFile.ReadLine\nstrLine3 = objFile.ReadLine\n<\/pre>\n<p>Both of these lines of code should be self-explanatory: in line 1 we use the ReadLine method to read the next line in the text file, and in line 2 we use the same method to read the line after that (the third line in the text file). The net result? The variable strLine2 will be equal to this:<\/p>\n<pre class=\"codeSample\">date, 1\/1\/2000\n<\/pre>\n<p>And the variable strLine3 will be equal to \u2013 well, that\u2019s right, line 3 in the text file:<\/p>\n<pre class=\"codeSample\">reference, 12345\n<\/pre>\n<table class=\"dataTable\" id=\"EMAAC\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. So did you really know that, or was that just a lucky guess? <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>We now have all the information we need to construct both records for Ken Myer. (Or to simply reconstruct his one record, if it turns out that we didn\u2019t find the word <i>Medical<\/i>.) We can put together record 1 by using the following line of code:<\/p>\n<pre class=\"codeSample\">strText = strText &amp; strLine1 &amp; vbCrLf &amp; strLine2 &amp; vbCrLf &amp; strLine3 &amp; vbCrLf\n<\/pre>\n<p>Here we\u2019re assigning a new value to the variable strText. That value will consist of the existing value of strText plus the following items:<\/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 value of strLine1 (Ken Myer, Medical, 1\/1\/1980), and a carriage return-linefeed (the VBScript constant <b>vbCrLf<\/b>).<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>The value of strLine2 (date, 1\/1\/2000) plus another carriage return-linefeed.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>The value of strLine3 (reference, 12345) plus one last carriage return-linefeed.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In other words, strText will be equal to this:<\/p>\n<pre class=\"codeSample\">Ken Myer, Medical, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12345\n<\/pre>\n<p>Next we check to see if the variable strDuplicateLine has a value (that is, the value is <i>not<\/i> equal to an empty string):<\/p>\n<pre class=\"codeSample\">If strDuplicateLine &lt;&gt; \"\" Then\n<\/pre>\n<p>If strDuplicateLine has a value that can mean only one thing: we found the word <i>Medical<\/i> in line 1 of this record, so we need to tack on the <i>Dental<\/i> record as well. That\u2019s what this line of code is for:<\/p>\n<pre class=\"codeSample\">strText = strText &amp; strDuplicateLine &amp; vbCrLf &amp; strLine2 &amp; vbCrLf &amp; strLine3 &amp; vbCrLf\n<\/pre>\n<p>See? In this case we use the variable strDuplicateLine, the variable in which we replaced the word <i>Medical<\/i> with the word <i>Dental<\/i>. That makes strText equal to this:<\/p>\n<pre class=\"codeSample\">Ken Myer, Medical, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12345\nKen Myer, Dental, 1\/1\/1980\ndate, 1\/1\/2000\nreference, 12345\n<\/pre>\n<p>Well, what do you know? Ken Myer now has two records \u2013 one Medical and one Dental \u2013 just like we wanted him to have.<\/p>\n<p>Once that\u2019s done we reset the value of strDuplicateLine to an empty string, then zip back to the top of the loop to repeat the process with the next line in the text file. (Which, if you recall, will actually be line <i>4<\/i> in the text file; that\u2019s because we\u2019ve already read lines 1, 2, and 3.) As soon as we finish reading the entire file we use the <b>Close<\/b> method to close Test.txt, then use this line of code to reopen the file, this time for writing:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForWriting)\n<\/pre>\n<p>From there we use the <b>Write<\/b> method to replace the existing contents of the file with the value of the variable strText, close the file one last time, and then call it a day.<\/p>\n<p>As for the Yahoo! deal, we have to admit that we\u2019re beginning to have second thoughts. As it turns out, we underestimated the number of people who own Yahoo! stock; Yahoo! actually has hundreds of thousands of shareholders rather than the 5 or 6 we assumed they had. What does that mean? That means that we don\u2019t actually have enough bobbleheads to go around. If you guys are willing to share, well, that would be great. Otherwise, what about this: what do you think about Yahoo! <i>buying<\/i> the Script Center? After all, what a great way to get back at Microsoft for making such a paltry offer for your company, eh? And just think about that for a moment: stealing Microsoft\u2019s crown jewel \u2013 the Script Center \u2013 away from them? Priceless.<\/p>\n<p>Well, not actually <i>priceless<\/i>, mind you; however, the Scripting Guys <i>are<\/i> willing to accept $42 billion for the Script Center. (Sure, the Script Center is probably worth more, but we\u2019re not greedy.) In fact, we\u2019ll even sweeten the deal a little: act before the end of the month, and we\u2019ll give you a 5% discount on top of everything else. Just let us know.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I need a script that can read a file and, based on the contents, insert some additional lines of text into that file. Can you help me with that?&#8212; JS Hey, JS. We\u2019re sure that most of you have heard by now that Microsoft has made an offer to buy Yahoo!, an [&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-55813","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 need a script that can read a file and, based on the contents, insert some additional lines of text into that file. Can you help me with that?&#8212; JS Hey, JS. We\u2019re sure that most of you have heard by now that Microsoft has made an offer to buy Yahoo!, an [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55813","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=55813"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55813\/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=55813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}