{"id":63903,"date":"2007-10-01T05:10:00","date_gmt":"2007-10-01T05:10:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/10\/01\/hey-scripting-guy-how-can-i-search-a-text-file-for-terms-read-in-from-a-second-text-file\/"},"modified":"2007-10-01T05:10:00","modified_gmt":"2007-10-01T05:10:00","slug":"hey-scripting-guy-how-can-i-search-a-text-file-for-terms-read-in-from-a-second-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-search-a-text-file-for-terms-read-in-from-a-second-text-file\/","title":{"rendered":"Hey, Scripting Guy! How Can I Search a Text File for Terms Read In From a Second 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 a text file that has a list of search terms in it. I would like to write a script that can search for each of those terms in a second file, and then report back any of the terms that couldn\u2019t be found in that second file. How do I do that?<BR><BR>&#8212; PH<\/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, PH. You know, this is a good day for the Scripting Guy who writes this column. That\u2019s somewhat surprising, too, because \u2013 until he figured out what was going on \u2013 it came perilously close to being a very bad day.<\/P>\n<P>Last night on his way home from work the Scripting Guy who writes this column stopped to buy two extra-large sandwiches, one for himself and one for the Scripting Son. As he paid for the two sandwiches the cashier asked him, \u201cIs this for here or to go?\u201d<\/P>\n<P>For <I>here<\/I>? The Scripting Guy who writes this column had just ordered two gigantic sandwiches, and he was the only customer in the restaurant at the time. For a moment, this Scripting Guy was crushed: obviously the cashier saw him as the kind of person who could wolf down two huge sandwiches all by himself, and without batting an eye. Say it isn\u2019t so: gluttony is one of the Seven Deadly Sins!<\/P>\n<TABLE id=\"EBD\" 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>. For those of you keeping track, the other Deadly Sins are: Lust; Greed; Sloth; Wrath; Envy; and Pride. Hey, what do you know: the Scripting Editor got a perfect score!<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>The Scripting Guy who writes this column was just about to storm out of the restaurant, never to return (well, at least not until he wanted another sandwich) when he realized what was going on. The cashier didn\u2019t think he was a gluttonous slob; far from it. Instead, she was worried that this poor little Scripting Guy \u2013 with his tiny little stomach and his birdlike appetite \u2013 was malnourished. She <I>wanted<\/I> him to eat both those sandwiches, because she figured a skinny guy like him could actually stand to <I>gain<\/I> a few pounds. Once he realized this, the Scripting Guy who writes this column simply smiled, left the girl a tip, and headed out the door.<\/P>\n<TABLE id=\"EUD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. Considering how often this column deals with the topic of doughnuts you might find it hard to believe that the Scripting Guy who writes this column is a lean, mean, scripting machine. That\u2019s understandable. But just ask the Scripting Editor. For example, the other day she watched as the Scripting Guy who writes this column ate a taco salad, but without eating the taco shell, not even one bite. See? Bird-like appetite.<\/P>\n<P><B>Ed<\/B><B>itor\u2019s Note:<\/B> Did you know the Ruby-Throat Hummingbird weighs 28 grams and eats 50 grams of food per day, almost twice its body weight? Yes, we\u2019d agree that the Scripting Guy who writes this column has a bird-like appetite.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>But don\u2019t worry about the Scripting Guy who writes this column; he might be skinny, but he\u2019s not malnourished. After all, if he <I>was<\/I> malnourished he\u2019d never be able to muster the strength to write a script that grabs terms from one text file and then searches for each of those terms in a second 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\\SearchText.txt&#8221;, ForReading)<\/p>\n<p>strContents = objFile.ReadAll\nobjFile.Close<\/p>\n<p>Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Terms.txt&#8221;, ForReading)<\/p>\n<p>strSearchTerms = objFile.ReadAll\nobjFile.Close<\/p>\n<p>arrSearchTerms = Split(strSearchTerms, vbCrLf)<\/p>\n<p>For Each strItem in arrSearchTerms\n    intFound = InStr(strContents, strItem)\n    If intFound = 0 Then\n        Wscript.Echo &#8220;The search term &#8221; &amp; strItem &amp; &#8221; was not found.&#8221;\n    End If\nNext\n<\/PRE>\n<P>Let\u2019s see if we can figure out how this works. To begin with, we define a constant named ForReading and assign it the value 1; we\u2019ll use this constant each time we open a text file. (And yes, we\u2019ll be working with two text files, but not because we\u2019re a glutton: PH <I>asked<\/I> us to work with two text files.) After defining the constant we create an instance of the <B>Scripting.FileSystemObject<\/B>, then use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\SearchText.txt for reading (this, by the way, happens to be the file we want to search):<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\SearchText.txt&#8221;, ForReading)\n<\/PRE>\n<P>After that we use the <B>ReadAll<\/B> method to read in the entire contents of the text file, storing that information in a variable named strContents. Of course, this also gives us a virtual copy of the file safely tucked away in memory. And that\u2019s good. Why? Because we\u2019re going to search this virtual copy as opposed to searching the actual text file itself. (Which is pretty much the way we <I>have<\/I> to do this.) With that in mind, we then call the <B>Close<\/B> method and close the file SearchText.txt.<\/P>\n<P>Got all that? Good. In case you\u2019re wondering, the contents of SearchText.txt (and thus the value of the variable strContents) look like this:<\/P><PRE class=\"codeSample\">&#8216;Curiouser and curiouser!&#8217; cried Alice (she was so much surprised, that \nfor the moment she quite forgot how to speak good English); &#8216;now I&#8217;m \nopening out like the largest telescope that ever was! Good-bye, feet!&#8217; \n(for when she looked down at her feet, they seemed to be almost out of \nsight, they were getting so far off). &#8216;Oh, my poor little feet, I wonder \nwho will put on your shoes and stockings for you now, dears? I&#8217;m sure \n_I_ shan&#8217;t be able! I shall be a great deal too far off to trouble myself \nabout you: you must manage the best way you can; &#8211;but I must be kind to \nthem,&#8217; thought Alice, &#8216;or perhaps they won&#8217;t walk the way I want to go!  \nLet me see: I&#8217;ll give them a new pair of boots every Christmas.&#8217;\n<\/PRE>\n<TABLE id=\"EEF\" 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>. <I>Alice<\/I><I> in Wonderland<\/I>? No, strangely enough, this is the kind of event the Scripting Guy who writes this column always ends up getting written to his event log.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Our next step is to call OpenTextFile one last time, on this occasion opening the file C:\\Scripts\\Terms.txt (which contains the items we want to search for). And then once again we call the <B>ReadAll<\/B> method, this time storing the extracted data in a variable named strSearchTerms:<\/P><PRE class=\"codeSample\">strSearchTerms = objFile.ReadAll\n<\/PRE>\n<P>And then we call the Close method and dismiss the file Terms.txt.<\/P>\n<P>That simply means that, at this point in time, the value of strSearchTerms looks like this (reflecting the data read in from the text file):<\/P><PRE class=\"codeSample\">boots\nhat\npants\nshirt\nshoes\ntelescope\n<\/PRE>\n<P>Is that good? Well, no, not really; after all, we need to search for each item separately. (That is, we need to search for the word <I>boots<\/I>, then do a second search for the word <I>hat<\/I>, then do a third search for the word <I>pants<\/I>, and so on.) In turn, that means that we somehow need to take this single list and divvy it up into individual search times.<\/P>\n<P>Which is exactly what this line of code is for:<\/P><PRE class=\"codeSample\">arrSearchTerms = Split(strSearchTerms, vbCrLf)\n<\/PRE>\n<P>Here we\u2019re simply using the <B>Split<\/B> function to convert the string value strSearchTerms into an array named arrSearchTerms. By splitting on the carriage return-linefeed character (vbCrLf) we end up with an array consisting of the following items:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>boots<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>hat<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>pants<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>shirt<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>shoes<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>telescope<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>If you\u2019re thinking, \u201cGee, each of those items looks an awful lot like one of the terms we want to search for,\u201d well, you\u2019re absolutely right: each item in the array <I>is<\/I> one of the terms we want to search for. Imagine that!<\/P>\n<P>Of course, it wouldn\u2019t be much fun to have a set of search terms and then not actually search for them, would it? That\u2019s what this block of code is for:<\/P><PRE class=\"codeSample\">For Each strItem in arrSearchTerms\n    intFound = InStr(strContents, strItem)\n    If intFound = 0 Then\n        Wscript.Echo &#8220;The search term &#8221; &amp; strItem &amp; &#8221; was not found.&#8221;\n    End If\nNext\n<\/PRE>\n<P>What we\u2019ve done here is set up a For Each loop to walk us through each item in the array arrSearchTerms. For each search term we use the <B>InStr<\/B> function to determine whether or not that value can be found anywhere in our text file (or, more precisely, anywhere in the value of the variable strContents). That\u2019s what this line of code is for:<\/P><PRE class=\"codeSample\">intFound = InStr(strContents, strItem)\n<\/PRE>\n<P>If the search term is found, InStr returns an integer corresponding to the character position in the string where the term begins. If the search term <I>can\u2019t<\/I> be found, then InStr returns a 0. How can we report back which terms can\u2019t be found in the file? That\u2019s easy; we simply check to see if the value of the variable intFound (the starting character position) is equal to 0:<\/P><PRE class=\"codeSample\">If intFound = 0 Then\n<\/PRE>\n<P>If intFound is anything <I>but<\/I> 0 that can only mean one thing: the search term appears somewhere in strContents. Thus if we get back a value other than 0 we simply go back to the top of the loop and repeat the process with the next term. If intFound <I>is<\/I> equal to 0, that can also mean only one thing: the search term doesn\u2019t appear anywhere in strContents. In that case, we echo back a message stating that the term in question could not be found:<\/P><PRE class=\"codeSample\">Wscript.Echo &#8220;The search term &#8221; &amp; strItem &amp; &#8221; was not found.&#8221;\n<\/PRE>\n<P>Using our sample text file and our sample search terms, that means we\u2019ll get back a report that looks like this:<\/P><PRE class=\"codeSample\">The search term pants was not found.\nThe search term shirt was not found.\n<\/PRE>\n<P>As soon as we\u2019ve finished looping through all the items in the array we can then call it a day. And what the heck, you can call it a day, too. Take the rest of the day off, and if your boss decides to dock you a day\u2019s pay, well, just send the bill to the Scripting Guys and we\u2019ll take care of it.<\/P>\n<TABLE id=\"E3H\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. The Scripting Editor is a little tired today, so we\u2019ll do her job for her: \u201cNow that we\u2019ve had a chance to reflect on this, please do <I>not<\/I> send the bill to the Scripting Guys after all. In fact, you shouldn\u2019t take the day off, either, even if your boss says it\u2019s OK; <I>stay at your desk and keep working<\/I>. Remember, idle hands are the Devil\u2019s plaything.\u201d<\/P>\n<P>You can see why we all love the Scripting Editor, can\u2019t you? She\u2019s just <I>so<\/I> much fun to have around.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>As a postscript, when the Scripting Guy who writes this column got home and took the sandwiches out of the bag, he discovered that the cashier had helpfully included about 253,000 napkins. Apparently she must have thought that the Scripting Son was a messy eater.<\/P>\n<TABLE id=\"EUAAC\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. <I>Is<\/I> the Scripting Son a messy eater? No. He\u2019s more like a piranha: when he finishes eating, there\u2019s not a single crumb or speck of food to be found anywhere.<\/P>\n<P>Which, now that you mention it, <I>does<\/I> make washing dishes a breeze.<\/P><\/TD><\/TR><\/TBODY><\/TABLE><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a text file that has a list of search terms in it. I would like to write a script that can search for each of those terms in a second file, and then report back any of the terms that couldn\u2019t be found in that second file. How do I [&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-63903","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 a text file that has a list of search terms in it. I would like to write a script that can search for each of those terms in a second file, and then report back any of the terms that couldn\u2019t be found in that second file. How do I [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63903","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=63903"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63903\/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=63903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}