{"id":65393,"date":"2007-03-03T01:08:00","date_gmt":"2007-03-03T01:08:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/03\/03\/how-can-i-modify-a-text-file-and-then-extract-selected-lines-from-the-modified-contents\/"},"modified":"2007-03-03T01:08:00","modified_gmt":"2007-03-03T01:08:00","slug":"how-can-i-modify-a-text-file-and-then-extract-selected-lines-from-the-modified-contents","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-modify-a-text-file-and-then-extract-selected-lines-from-the-modified-contents\/","title":{"rendered":"How Can I Modify a Text File and Then Extract Selected Lines From the Modified Contents?"},"content":{"rendered":"<p><H2><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\"> <\/H2>\n<P>Hey, Scripting Guy! How can I write a script that modifies the contents of a text file and then copies specified lines from the modified contents to a new file?<BR><BR>&#8212; EH<\/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, EH. There\u2019s no way to do that. Now go away and leave us alone.<\/P>\n<P>Wait, sorry; we didn\u2019t mean it. As it turns out, the Scripting Guy who writes this column is in a terrible mood this morning. Admittedly, he\u2019s in a terrible mood pretty much <I>every<\/I> morning, but at least today he has good reason to be grumpy. He\u2019s writing this column on March 1, and when he awoke this morning his house and everything around it was covered with a good two inches of snow. <I>Snow<\/I>, mind you, and on March 1<SUP>st<\/SUP>! The Scripting Son has already started high school baseball practice and there are two inches of snow on the ground! The Scripting Guy who writes this column fully intends to sue someone over this. He just has to figure out <I>who<\/I> he can sue over this.<\/P>\n<P>And yes, we know: people in, say, New York, who recently dealt with several <I>feet<\/I> of snow, don\u2019t feel too sorry for Seattleites who have to deal with a few piddling inches of snow, snow that\u2019s already beginning to melt even as we speak. But that\u2019s OK. After all, we don\u2019t need anyone\u2019s pity; we have more than enough self-pity to go around. In the past few months we\u2019ve had ice storms; power failures (leaving the Scripting Guy who writes this column without electricity for 6 long, cold, and very dark days); more ice storms; and now snow on March 1<SUP>st<\/SUP>. What did we ever do to deserve all <I>that<\/I>?<\/P>\n<P>OK, we can\u2019t argue with you there. But surely the entire Seattle area shouldn\u2019t have to pay for the sins of one Scripting Guy.<\/P>\n<P>Oh, well. At any rate, we apologize for starting this column out on such a rude note. Tell you what, EH: is there some way we can make this up to you? What\u2019s that? Show you how to write a script that modifies the contents of a text file and then copies specified lines from the modified contents to a new file? Hmmm; we never would of have thought of that. OK, EH; here you go:<\/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>strContents = objFile.ReadAll\nobjFile.Close<\/p>\n<p>strContents = Replace(strContents, &#8220;~&#8221;, &#8220;~&#8221; &amp; vbCrLf)<\/p>\n<p>arrLines =Split(strContents, vbCrLf)<\/p>\n<p>For Each strLine in arrLines\n    If Left(strLine, 2) = &#8220;N9&#8221; or Left(strLine, 2) = &#8220;B4&#8221; Then\n        strNewFile = strNewFile &amp; strLine &amp; vbCrLf\n    End If\nNext<\/p>\n<p>Set objFile = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Test2.txt&#8221;)\nobjFile.Write strNewFile\nobjFile.Close\n<\/PRE>\n<P>And now can we explain how the script works? How in the world are <I>we<\/I> supposed to know how the script works?!? Now go away and leave us alone.<\/P>\n<P>Sorry; guess we aren\u2019t quite back to our usual jolly and carefree selves here. Sure, we can explain how this script works. As you can see, we start off by creating a constant named ForReading and setting the value to 1; we\u2019ll use this constant when we open our text file. In fact, we\u2019ll use this constant in the following block of code, code that creates an instance of the <B>Scripting.FileSystemObject<\/B> and then uses the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.txt:<\/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>As you noted in your email, EH, you have a crazy text file that looks something like this, with everything on one big long line:<\/P><PRE class=\"codeSample\">*070219*1347*U*00401*000000852*0*P*&gt;~GS*QO*CMACGM*USALTLANP*20070219*1347*85\n2*X*004010~ST*315*0001~B4***CT*20070219*0840*1703*CAXU*983290*L*4510~N9*BM*SZ2\n711711~N9*BN*SHZ438713~N9*SN*C4025491~Q2*9227027*****166***PX311E***L*CSCL\nDALIAN~R4*L*K*57078*YANTIAN~DTM*140*20070119*1200~R4*D*D*1703*SAVANNAH, GA~\n<\/PRE>\n<TABLE class=\"dataTable\" id=\"EHE\" 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>. It\u2019s probably none of our business, but are you a spy or something, EH? You\u2019re right; maybe it\u2019s best if we <I>don\u2019t<\/I> know that.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>You\u2019d like to read in this text file and do two things. First, you\u2019d like to put a carriage return-linefeed after each tilde character (~); that will give you lines that look like this:<\/P><PRE class=\"codeSample\">*070219*1347*U*00401*000000852*0*P*&gt;~\nGS*QO*CMACGM*USALTLANP*20070219*1347*852*X*004010~\nST*315*0001~\nB4***CT*20070219*0840*1703*CAXU*983290*L*4510~\nN9*BM*SZ2711711~\nN9*BN*SHZ438713~\nN9*SN*C4025491~\nQ2*9227027*****166***PX311E***L*CSCL DALIAN~\nR4*L*K*57078*YANTIAN~\nDTM*140*20070119*1200~\nR4*D*D*1703*SAVANNAH, GA~\n<\/PRE>\n<P>After that you\u2019d then like to identify any lines that begin with <B>N9<\/B> or <B>B4<\/B> and copy those lines to a separate text file. Sounds crazy, doesn\u2019t it? But if it\u2019s crazy you want, well, you came to the right place.<\/P>\n<P>To begin with, we use the <B>ReadAll<\/B> method to read the entire file into memory and store the contents in a variable named strContents:<\/P><PRE class=\"codeSample\">strContents = objFile.ReadAll\n<\/PRE>\n<P>We then immediately close the file C:\\Scripts\\Test.txt. Why? Because we don\u2019t need it anymore; we\u2019ll do all our work with the variable strContents instead.<\/P>\n<P>For starters, let\u2019s put a carriage return-linefeed after each tilde in the file. How are we going to do that? Like this:<\/P><PRE class=\"codeSample\">strContents = Replace(strContents, &#8220;~&#8221;, &#8220;~&#8221; &amp; vbCrLf)\n<\/PRE>\n<P>As you can see, we simply use the <B>Replace<\/B> function to replace each tilde character with <I>two<\/I> characters: a tilde and a carriage return-linefeed (as indicated by the VBScript constant <B>vbCrLf<\/B>). The net effect: the tildes remain exactly where they are, only there\u2019s now a carriage return-linefeed after each one.<\/P>\n<P>Of course, something else has happened here as well: our text file (or at least the virtual copy of that file) now has multiple lines thanks to the carriage return-linefeed. And because it <I>does<\/I> have multiple lines we can go ahead and extract all the lines that begin with N9 or B4.<\/P>\n<P>In order to do that we first use the <B>Split<\/B> function to split the variable strContents on the carriage return-linefeed character:<\/P><PRE class=\"codeSample\">arrLines =Split(strContents, vbCrLf)\n<\/PRE>\n<P>That\u2019s going to result in an array (arrLines) in which each element represents a line in the text file. In turn, that means we can now \u201cread\u201d each line in the file simply by setting up a For Each loop that walks through all the items in the array:<\/P><PRE class=\"codeSample\">For Each strLine in arrLines\n<\/PRE>\n<P>So what are we going to do inside that loop? Well, for each array item we\u2019re going to check to see if the first two characters are either N9 or B4; that\u2019s what this line of code, and the <B>Left<\/B> function, are for:<\/P><PRE class=\"codeSample\">If Left(strLine, 2) = &#8220;N9&#8221; or Left(strLine, 2) = &#8220;B4&#8221; Then\n<\/PRE>\n<P>Let\u2019s suppose we find one of the target lines. In that case, we simply take that value and append it (plus a carriage return-linefeed character) to a variable named strNewFile:<\/P><PRE class=\"codeSample\">strNewFile = strNewFile &amp; strLine &amp; vbCrLf\n<\/PRE>\n<P>And then we loop around and repeat this process with the next item in the array.<\/P>\n<P>Once we\u2019ve finished looping through the array we then execute this block of code:<\/P><PRE class=\"codeSample\">Set objFile = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Test2.txt&#8221;)\nobjFile.Write strNewFile\nobjFile.Close\n<\/PRE>\n<P>All we\u2019re doing here is creating a new file named C:\\Scripts\\Test2.txt; that\u2019s what we do with the <B>CreateTextFile<\/B> method. We use the <B>Write<\/B> method to write the value of strNewFile to Test2.txt, then close the file and call it good. If we then open Test2.txt we should see this:<\/P><PRE class=\"codeSample\">B4***CT*20070219*0840*1703*CAXU*983290*L*4510~\nN9*BM*SZ2711711~\nN9*BN*SHZ438713~\nN9*SN*C4025491~\n<\/PRE>\n<P>Which, crazy as it might seem, is exactly what we <I>wanted<\/I> to see.<\/P>\n<P>Now, if you\u2019ll excuse us, we\u2019re going to go back to being grumpy and feeling sorry for ourselves. Admittedly, right now the sun is peeking through the clouds, and the snow is rapidly melting. But we\u2019re not going to fall for that old trick; the sun coming out simply means that we\u2019ll have a nice clear view of the next disaster to strike the Seattle area. We\u2019re betting on frogs or locusts; it\u2019s been awhile since we\u2019ve had a plague of frogs or locusts around here. We\u2019ll let you know.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I write a script that modifies the contents of a text file and then copies specified lines from the modified contents to a new file?&#8212; EH Hey, EH. There\u2019s no way to do that. Now go away and leave us alone. Wait, sorry; we didn\u2019t mean it. As it turns [&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-65393","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 write a script that modifies the contents of a text file and then copies specified lines from the modified contents to a new file?&#8212; EH Hey, EH. There\u2019s no way to do that. Now go away and leave us alone. Wait, sorry; we didn\u2019t mean it. As it turns [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65393","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=65393"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65393\/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=65393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=65393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=65393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}