{"id":55633,"date":"2008-05-06T01:32:00","date_gmt":"2008-05-06T01:32:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/05\/06\/hey-scripting-guy-how-can-i-search-for-a-word-in-a-text-file-and-return-the-entire-line-where-that-word-was-found\/"},"modified":"2008-05-06T01:32:00","modified_gmt":"2008-05-06T01:32:00","slug":"hey-scripting-guy-how-can-i-search-for-a-word-in-a-text-file-and-return-the-entire-line-where-that-word-was-found","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-search-for-a-word-in-a-text-file-and-return-the-entire-line-where-that-word-was-found\/","title":{"rendered":"Hey, Scripting Guy! How Can I Search for a Word in a Text File and Return the Entire Line Where That Word Was Found?"},"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 have a scenario in which I need to read a list of names from a text file. I then need to search for each of those names in a second text file; if a name is found I need to extract the entire line in which that name appears. I\u2019ve figured out how to search for a name in a text file, but I can\u2019t figure out how to extract the entire line in which that name appears. Can you help me?<br \/>&#8212; DS<\/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, DS. Today is May 5<sup>th<\/sup>, Cinco de Mayo. Cinco de Mayo is actually the Scripting Guy who writes this column\u2019s favorite holiday; that\u2019s because this holiday is primarily celebrated in America, and yet the average American has no idea what it is he or she is celebrating. Most Americans think that Cinco de Mayo is Mexico\u2019s Independence Day; it\u2019s not. (And why would the average American be so excited about celebrating Mexico Independence Day anyway? Well, we\u2019re not sure, but we\u2019re willing to bet that Mexican beer has something to do with it.)<\/p>\n<p>Instead, Cinco de Mayo actually pays homage to the 1862 Battle of Puebla. Back then, due to a severe financial crisis, Mexico stopped payment on its foreign debts, a very high percentage of which were owed to France. The French weren\u2019t too happy about this, so they sent an army across the ocean and invaded Mexico. An outmanned and outgunned Mexican army defeated the French at the Battle of Puebla, and the country was saved.<\/p>\n<p>Well, for awhile anyway: a year later the French launched a second invasion, overran the capital city, and installed the Emperor Maximilian of Hapsburg as the new ruler of Mexico. It would be another 5 years before the Mexicans were able to regain their independence.<\/p>\n<p>In other words, Mexico won the Battle of Puebla but lost the war. But hey, that\u2019s still one more victory than the Scripting Guys have ever had.<\/p>\n<p>As we noted, Cinco de Mayo is primarily an American holiday, one designed to celebrate Mexican culture. And how do Americans celebrate Mexican culture? Well, a large number of them seem to celebrate Mexican culture by drinking beer at an Irish pub; an Internet search for <i>Cinco de Mayo<\/i> and <i>Irish pub<\/i> returned 143,000 hits. That\u2019s about the same number of hits returned for <i>Cinco de Mayo<\/i> and <i>Mexican restaurant<\/i>.<\/p>\n<p>Sadly enough, though, a search for <i>Cinco de Mayo<\/i> and <i>system administration scripting<\/i> returned zero hits; for some reason, people don\u2019t associate Cinco de Mayo with system administration scripting. But don\u2019t despair; after all, that\u2019s a problem the Scripting Guys can rectify, and right away:<\/p>\n<pre class=\"codeSample\">Const ForReading = 1\n\nSet objFSO = CreateObject(\"Scripting.FileSystemObject\")\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n\nstrTargetText = objFile.ReadAll\nobjFile.Close\n\nSet objRegEx = CreateObject(\"VBScript.RegExp\")\nobjRegEx.Global = True  \n\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Names.txt\", ForReading)\n\nDo Until objFile.AtEndOfStream\n    strName = objFile.ReadLine\n    objRegEx.Pattern = \".{0,}\" &amp; strName &amp; \".{0,}\\n\"\n    Set colMatches = objRegEx.Execute(strTargetText)  \n\n    If colMatches.Count &gt; 0 Then\n       For Each strMatch in colMatches   \n           strText = strText &amp; strMatch.Value \n       Next\n    End If\nLoop\n\nWscript.Echo strText\n<\/pre>\n<p>Before we talk about the script and how it works we should explain the scenario in a little more detail. DS has a text file (C:\\Scripts\\Test.txt) that includes lines similar to these:<\/p>\n<pre class=\"codeSample\">192.168.0.0, this is sql users, tom, testmachine \n192.168.1.2, this is mysql users, john, testmachine2 \n192.168.0.0, this is sql users, joseph, testmachine5 \n192.168.0.3, this is sql users, maria, testmachine6 \n192.168.0.5, this is sql users, donald, testmachine7 \n192.168.0.6, this is sql users, tom, testmachine11\n<\/pre>\n<p>In addition, he has a second text file (C:\\Scripts\\Names.txt) that includes user names like the following:<\/p>\n<pre class=\"codeSample\">tom\npeter\njoseph\n<\/pre>\n<p>What DS needs to do is search Test.txt for each of these names, reporting back any lines where a given name is found. For example, when the script searches for <i>joseph<\/i> it needs to return this entire line:<\/p>\n<pre class=\"codeSample\">192.168.0.0, this is sql users, joseph, testmachine5\n<\/pre>\n<p>Sounds like an impossible task? Let\u2019s put it this way: that\u2019s what the naysayers said about the Battle of Puebla.<\/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>. In case you\u2019re wondering, the <a href=\"http:\/\/babelfish.altavista.com\/tr\" target=\"_blank\"><b>Babelfish<\/b><\/a> Web site tells us that the Spanish word for naysayer is, well, naysayer.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>We start our script off by defining a constant named ForReading and setting the value to 1; we\u2019ll need this constant when we open our text files for reading. After defining the constant we create an instance of the <b>Scripting.FileSystemObject<\/b>, then use this line of code to open the file Test.txt:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n<\/pre>\n<p>And what do we do with that file once it\u2019s open? To tell you the truth, not much; in fact, all we\u2019re going to do is use the <b>ReadAll<\/b> method to read in the entire contents of the file, storing that information in a variable named strTargetText:<\/p>\n<pre class=\"codeSample\">strTargetText = objFile.ReadAll\n<\/pre>\n<p>At that point we call the <b>Close<\/b> method and never touch Test.txt again. Why not? Because we don\u2019t need it anymore; instead, we\u2019ll conduct all our searches on the virtual copy of Test.txt stored in the variable strTargetText.<\/p>\n<p>Next we create an instance of the <b>VBScript.RegExp<\/b> object, the object that enables us to do regular expression searches within a VBScript script:<\/p>\n<pre class=\"codeSample\">Set objRegEx = CreateObject(\"VBScript.RegExp\")\n<\/pre>\n<p>We set the <b>Global<\/b> property of our regular expressions object to True (to make sure that we find all the possible matches in the target text), then reuse the FileSystemObject and open the file Names.txt:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Names.txt\", ForReading)\n<\/pre>\n<p>Now we\u2019re ready to actually do something useful. To begin with, we set up a Do Until loop that runs until the file\u2019s <b>AtEndOfStream<\/b> property is True; that simply means that we\u2019re going to keep reading the file until there\u2019s nothing left to read. Inside this loop we use the <b>ReadLine<\/b> method to read in the first line (the first name) from the text file, storing that value in the variable strName:<\/p>\n<pre class=\"codeSample\">strName = objFile.ReadLine\n<\/pre>\n<p>That brings us to this line of code:<\/p>\n<pre class=\"codeSample\">objRegEx.Pattern = \".{0,}\" &amp; strName &amp; \".{0,}\\n\"\n<\/pre>\n<p>What we\u2019re doing here is telling the script exactly what text we\u2019re searching for. And what text <i>are<\/i> we searching for? Well, for starters, the construction <b>.{0,}<\/b> means we\u2019re searching for zero or more instances of any character (that\u2019s what the <b>. <\/b>represents) <i>except for<\/i> the carriage return linefeed character. In other words, we want some characters (any characters except the carriage return-linefeed characters) followed by the name we just read in from the text file. That name must then be followed by 0 or more characters, followed \u2013 at long last \u2013 by a carriage return-linefeed (<b>\\n<\/b>). <\/p>\n<p>So why do search for all that even though we\u2019re just looking for a name like <i>tom<\/i> or <i>joseph<\/i>? One reason and one reason only: that\u2019s how we can extract an entire line from the file. After all, we\u2019re no longer searching for the name <i>tom<\/i>; we\u2019re now searching for a line of text that happens to include the name <i>tom<\/i>. It looks a little crazy (as do many regular expressions), but it works.<\/p>\n<p>After we assign the value to the <b>Pattern<\/b> property we then use this line of code to search strTargetText for that pattern:<\/p>\n<pre class=\"codeSample\">Set colMatches = objRegEx.Execute(strTargetText)\n<\/pre>\n<p>Any instances of the pattern we find will be placed in a collection we named colMatches. How do we know if we actually found any instances of the pattern? That\u2019s easy; we simply check the value of the collection\u2019s <b>Count<\/b> property:<\/p>\n<pre class=\"codeSample\">If colMatches.Count &gt; 0 Then\n<\/pre>\n<p>If the Count is equal to 0 that means that the pattern could not be found; in that case we simply go back to the top of the loop and try again with the next name in the text file. If the Count is greater than 0 that means at least one match <i>was<\/i> found. With that in mind, we use a For Each loop to loop through all the matches in the collection, adding the value of each match (in effect, the line from the text file) to a variable named strText:<\/p>\n<pre class=\"codeSample\">strText = strText &amp; strMatch.Value\n<\/pre>\n<p>After we\u2019ve run similar searches for all the names in the text file we then echo back the value of strText. If all goes according to plan, that should give us output like this:<\/p>\n<pre class=\"codeSample\">192.168.0.0, this is sql users, tom, testmachine\n192.168.0.6, this is sql users, tom, testmachine11\n192.168.0.0, this is sql users, joseph, testmachine5\n<\/pre>\n<p>Perfect! Or, as they say in Spanish, perfecto!<\/p>\n<p>Speaking of Spanish, the term <i>Cinco de Mayo<\/i> translates to the fifth of May. The Scripting Guy who writes this column grew up in the Tri-Cities, WA. Try to guess when the Tri-Cities held <i>its<\/i> Cinco de Mayo celebration this year. You\u2019re right: May <i>3<\/i><sup>rd<\/sup>.<\/p>\n<p>See? It\u2019s not his fault that the Scripting Guy who writes this column turned out the way he did.<\/p>\n<p>Well, not entirely, anyway.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a scenario in which I need to read a list of names from a text file. I then need to search for each of those names in a second text file; if a name is found I need to extract the entire line in which that name appears. I\u2019ve figured [&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-55633","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 scenario in which I need to read a list of names from a text file. I then need to search for each of those names in a second text file; if a name is found I need to extract the entire line in which that name appears. I\u2019ve figured [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55633","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=55633"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55633\/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=55633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}