{"id":64833,"date":"2007-05-18T23:01:00","date_gmt":"2007-05-18T23:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/05\/18\/how-can-i-search-every-text-file-in-a-folder-for-phone-numbers\/"},"modified":"2007-05-18T23:01:00","modified_gmt":"2007-05-18T23:01:00","slug":"how-can-i-search-every-text-file-in-a-folder-for-phone-numbers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-search-every-text-file-in-a-folder-for-phone-numbers\/","title":{"rendered":"How Can I Search Every Text File in a Folder For Phone Numbers?"},"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! In <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/may07\/hey0517.mspx\"><B>yesterday\u2019s column<\/B><\/A> you showed us how to search for phone numbers in a text file; you also promised us that in today\u2019s column you\u2019d show us how to modify that script so that it can search through all the text files in a folder. Are you still going to do that?<BR><BR>&#8212; SE<\/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, SE. Yes, we\u2019re going to \u2013 wait a second. <I>SE<\/I>? Interesting; you have the exact same initials as the <B>S<\/B>cripting <B>E<\/B>ditor, the same Scripting Editor who began nagging the Scripting Guy who writes this column the very second he said he was going to do a two-part <I>Hey, Scripting Guy! <\/I>this time around. \u201cTwo parts? Why are you doing two parts?\u201d said <I>our<\/I> SE. \u201cYou always say you\u2019re going to do a second part or a third part of something and then you never do it. What I think you should do is blah, blah, blah, blah \u2026.\u201d<\/P>\n<TABLE class=\"dataTable\" id=\"ERD\" 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>. To be honest, she didn\u2019t actually say \u201cblah, blah, blah, blah.\u201d Or at least we don\u2019t <I>think<\/I> she did. By then we\u2019d kind of lost interest.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>At any rate, SE \u2013 whoever you are \u2013 yes, we <I>are<\/I> going to show you how you can search for phone numbers in all the text files found in a specified folder. Before we do that, however, we feel we should apologize to our readers. After all, we assume that none of you were able to sleep last night, tossing and turning and fretting and fuming, thinking to yourself, \u201cHow could they do this to me? How am I supposed to sleep, heck, how am I supposed to do <I>anything<\/I> until I find out how this story ends? How <I>can<\/I> I search for phone numbers in all the text files found in a specified folder?\u201d You guys are right: that was a terrible thing for us to do, and we apologize. Never again will we do a multi-part <I>Hey, Scripting Guy! <\/I>column.<\/P>\n<P>At least not until the next time we do a multi-part <I>Hey, Scripting Guy!<\/I> column.<\/P>\n<P>And yes, we know: the suspense is <I>killing<\/I> you, isn\u2019t it? Therefore, without any further ado, let\u2019s take a look at a script that can open up all the files in the folder C:\\Scripts and then search for (and echo back) any phone numbers found in those files:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)<\/p>\n<p>strComputer = &#8220;.&#8221;<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colFileList = objWMIService.ExecQuery _\n    (&#8220;ASSOCIATORS OF {Win32_Directory.Name=&#8217;C:\\Scripts&#8217;} Where &#8221; _\n        &amp; &#8220;ResultClass = CIM_DataFile&#8221;)<\/p>\n<p>For Each objFile In colFileList\n    strName = objFile.FileName \n    strName = Replace(strName, &#8220;_&#8221;, &#8221; &#8220;)\n    Wscript.Echo strName<\/p>\n<p>    Set objFile = objFSO.OpenTextFile(objFile.Name, ForReading)\n    strSearchString = objFile.ReadAll\n    objFile.Close<\/p>\n<p>    Set objRegEx = CreateObject(&#8220;VBScript.RegExp&#8221;)<\/p>\n<p>    objRegEx.Global = True   \n    objRegEx.Pattern = &#8220;\\d{3}-\\d{3}-\\d{4} \\([a-zA-Z]*\\)&#8221;<\/p>\n<p>    Set colMatches = objRegEx.Execute(strSearchString)  <\/p>\n<p>    If colMatches.Count &gt; 0 Then\n       For Each strMatch in colMatches   \n           Wscript.Echo strMatch.Value \n       Next\n    End If<\/p>\n<p>    Wscript.Echo\nNext\n<\/PRE>\n<P>You\u2019re right: this <I>is<\/I> a fairly long script, at least for a <I>Hey, Scripting Guy!<\/I> column. But don\u2019t fret; remember, we went over most of this in <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/may07\/hey0517.mspx\"><B>yesterday\u2019s column<\/B><\/A>. Therefore, we\u2019re going to skip the part about using regular expressions to search for phone numbers and focus, instead, on getting that search to take place against all the files in a folder.<\/P>\n<P>Our first step in <I>that<\/I> journey (after defining the constant ForReading and after creating an instance of the <B>Scripting.FileSystemObject<\/B>) is to connect to the WMI service on the local computer. And before you ask, no, you can\u2019t use this script as-is to search text files on a remote computer; that\u2019s because the FileSystemObject isn\u2019t designed for working remotely. That doesn\u2019t mean that it\u2019s impossible to search files on a remote machine, it just means that you\u2019ll have to make some additional modifications before you can do so. For more information, see our column <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/oct05\/hey1021.mspx\"><B>How Can I Read a Text File on a Remote Computer?<\/B><\/A><\/P>\n<P>Hmmm, you know we <I>could<\/I> turn this into a three-part column \u2013 well, never mind; we don\u2019t like the look the Scripting Editor just gave us. Forget we even mentioned that.<\/P>\n<P>After we make the connection to the WMI service we then use this line of code to retrieve a collection of all the files found in the folder C:\\Scripts:<\/P><PRE class=\"codeSample\">Set colFileList = objWMIService.ExecQuery _\n    (&#8220;ASSOCIATORS OF {Win32_Directory.Name=&#8217;C:\\Scripts&#8217;} Where &#8221; _\n        &amp; &#8220;ResultClass = CIM_DataFile&#8221;)\n<\/PRE>\n<P>What\u2019s that? You say that your text files aren\u2019t in a folder named C:\\Scripts? Uh-oh \u2026.<\/P>\n<P>Nah, just kidding: all you have to do is replace the path C:\\Scripts with the path to the folder where your text files <I>are<\/I> located. For example, if your text files are in D:\\Employees then you need to use <I>this<\/I> line of code:<\/P><PRE class=\"codeSample\">Set colFileList = objWMIService.ExecQuery _\n    (&#8220;ASSOCIATORS OF {Win32_Directory.Name=&#8217;D:\\Employees&#8217;} Where &#8221; _\n        &amp; &#8220;ResultClass = CIM_DataFile&#8221;)\n<\/PRE>\n<P>Admittedly, these Associators Of queries are nasty looking, to say the least. But their bark is far worse than their bite.<\/P>\n<P>Once we get our collection back we then set up a For Each loop to loop through all the items in that collection (that is, through all the files in the folder C:\\Scripts). The first thing we do inside that loop is execute this block of code:<\/P><PRE class=\"codeSample\">strName = objFile.FileName \nstrName = Replace(strName, &#8220;_&#8221;, &#8221; &#8220;)\nWscript.Echo strName\n<\/PRE>\n<P>As we noted yesterday (typical Scripting Guys: always living in the past) we have a series of files with names like this:<\/P><PRE class=\"codeSample\">Jonathan_Haas.txt\nKen_Myer.txt\nPilar_Ackerman.txt\n<\/PRE>\n<P>As you can see, each file is named after the employee whose personal data is stored in that file. Does that matter? Yes, it does. Yesterday we only searched one file (Ken_Myer.txt); because that file path was hard-coded into our script it wasn\u2019t too hard to figure out whose phone numbers we were retrieving. (No, sorry, Scripting Editor; the correct answer is this: Ken Myer\u2019s.) Today, however, things have changed: today we\u2019re retrieving a bunch of different phone numbers belonging to a bunch of different people. Needless to say, we need some way to keep track of which phone numbers belong to which employee.<\/P>\n<P>And thanks to our file-naming convention we can do this simply by retrieving the name of the file and then making a tiny little tweak to the file name. In our first line of code we retrieve the value of the <B>FileName<\/B> property (that\u2019s the name of the file, minus the file extension) and store it in a variable named strName:<\/P><PRE class=\"codeSample\">strName = objFile.FileName\n<\/PRE>\n<P>That\u2019s going to make strName equal to this:<\/P><PRE class=\"codeSample\">Jonathan_Haas\n<\/PRE>\n<P>That\u2019s OK, but we decided to go one step further and replace the underscore character with a blank space. Interestingly enough, we do that by using the VBScript <B>Replace<\/B> function, replacing the underscore (_) with a blank space (\u201c \u201c):<\/P><PRE class=\"codeSample\">strName = Replace(strName, &#8220;_&#8221;, &#8221; &#8220;)\n<\/PRE>\n<P>Guess what we see onscreen when we echo back the new value of strName? Um, no, sorry again, Scripting Editor; the correct answer is this:<\/P><PRE class=\"codeSample\">Jonathan Haas\n<\/PRE>\n<TABLE class=\"dataTable\" id=\"E1G\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P><B>Note<\/B>. This is a tough day today for the Scripting Editor, isn\u2019t it? We think she\u2019s just in shock because the Scripting Guy who writes this column said he was going to do something (write both parts of a two-part series) and then he actually went ahead and did what he said he was going to do.<\/P>\n<P>Which means there really <I>is<\/I> a first time for everything.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After echoing back the employee name we\u2019re now ready to search the first file (Jonathan_Haas.txt) for phone numbers. From here on most of the script is exactly the same as the code we showed you yesterday. One major exception: when we call the <B>OpenTextFile<\/B> method (which we need to do in order to open and read the text file) we don\u2019t use a hard-coded file path like C:\\Scripts\\Ken_Myer.txt. Instead, we pass the method the value of the <B>Name<\/B> property (which just happens to be equivalent to the file path):<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(objFile.Name, ForReading)\n<\/PRE>\n<P>From there we go ahead and read the file, store the contents in a variable named strSearchString, then use a regular expression to search those contents for phone numbers. After echoing the back any phone numbers found in the file we then use the <B>Wscript.Echo<\/B> statetment to echo a blank line to the screen. Having finished with Jonathan Haas, we then loop around and repeat the process with the next file in the collection. When we\u2019re all done our screen should look something like this:<\/P><PRE class=\"codeSample\">Jonathan Haas\n425-555-4241 (office)\n425-555-9977 (home)<\/p>\n<p>Ken Myer\n425-555-1212 (office)\n425-555-5656 (cell)\n425-555-3434 (home)<\/p>\n<p>Pilar Ackerman\n425-555-2134 (office)\n425-555-6341 (cell)\n425-555-8900 (home)\n<\/PRE>\n<P>And there you have it. Do you want to perform some task (like search for phone numbers) against all the files in a folder? No problem; just follow this pattern: Use WMI to retrieve a collection of all those files, then use the Name property to grab the path for that file (for example, if you need to pass that path to another object, like the FileSystemObject). Readers are always asking us how to perform reading\/writing tasks against all the files in a folder; well, now you know!<\/P>\n<P>At any rate, that concludes our two-part episode on searching text files for phone numbers. Like we said, we\u2019ll try to steer clear of multi-part series\u2019 from now on. Granted, that\u2019s going to cause some problems for the Scripting Guys; for one thing, we\u2019re not totally sure what we\u2019re going to do with the first 67 columns for our intended 300-part series on declaring variables. But don\u2019t worry about it; we\u2019ll think of something.<\/P>\n<TABLE class=\"dataTable\" id=\"E2H\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P><B>Note<\/B>. Were we <I>really<\/I> going to write a 300-part series on declaring variables? No, not really. Instead, we were just going to write the first 5 or 6 parts and then simply re-run them over and over again. We figured that, after reading 5 consecutive columns on declaring variables, there wouldn\u2019t be any readers (or editors) left to notice that we were just running the same 5 columns day after day.<\/P>\n<P>And you\u2019re right: some days it\u2019s kind of hard to tell anyway, isn\u2019t it?<\/P><\/TD><\/TR><\/TBODY><\/TABLE><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! In yesterday\u2019s column you showed us how to search for phone numbers in a text file; you also promised us that in today\u2019s column you\u2019d show us how to modify that script so that it can search through all the text files in a folder. Are you still going to do that?&#8212; [&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":[11,3,4,12,14,5],"class_list":["post-64833","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-folders","tag-scripting-guy","tag-scripting-techniques","tag-storage","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! In yesterday\u2019s column you showed us how to search for phone numbers in a text file; you also promised us that in today\u2019s column you\u2019d show us how to modify that script so that it can search through all the text files in a folder. Are you still going to do that?&#8212; [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64833","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=64833"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64833\/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=64833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}