{"id":55493,"date":"2008-05-24T01:49:00","date_gmt":"2008-05-24T01:49:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/05\/24\/hey-scripting-guy-how-can-i-extract-miscellaneous-computer-names-from-a-text-file\/"},"modified":"2008-05-24T01:49:00","modified_gmt":"2008-05-24T01:49:00","slug":"hey-scripting-guy-how-can-i-extract-miscellaneous-computer-names-from-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-extract-miscellaneous-computer-names-from-a-text-file\/","title":{"rendered":"Hey, Scripting Guy! How Can I Extract Miscellaneous Computer Names From 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 have a text file containing thousands of events. I need to read each line in that file and look for the name of the computer where an operation failed. The computer names can \u2013 and will \u2013 vary in length; however, the name will always begin in character position 37, and be followed by the word <i>failed<\/i>. Oh, and there\u2019s one other complication: some of my lines have less than 40 characters, and there\u2019s no need to try to find a computer name in lines that small. How can I extract the appropriate computer names from this file?<br \/>&#8212; DA<\/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, DA. You know, yesterday morning when the Scripting Guy who writes this column left for work, he drove to the top of his hill and was immediately met by a deputy sheriff and a huge, snaking line of cars.<\/p>\n<p>Now, admittedly, it isn\u2019t all that unusual for the Scripting Guy who writes this column to find an angry mob congregating outside his house. (He really <i>should<\/i> learn to stop making fun of soccer, NASCAR racing, and the University of Oregon.) This time, however, the mob didn\u2019t appear to be particularly angry, and they weren\u2019t the least bit interested in the Scripting Guy who writes this column. Instead, a gas station about six blocks away, in conjunction with a local radio station, was having a Great Gas Giveaway: they were giving away $40 worth of free gas to each of the first 200 customers who pulled into the gas station, and even though the promotion wouldn\u2019t begin for another 30 minutes or so, the cars were already lined up for miles.<\/p>\n<p>Or at least for a third of a mile, anyway. <\/p>\n<p>The Scripting Guy who writes this column didn\u2019t stick around to watch the fun, or to try and get the free gas. He was amazed, however, at the fortitude and determination of the people who <i>were<\/i> planning to stick around and get the free gas: after all, the cars at the front of the line had undoubtedly been there for an hour or two (at least), and the cars at the back of the line were a good hour or two (at least) from getting their turn at the pump. And all just to get $40 worth of gas.<\/p>\n<p>Which, considering the price of gas these days, might be just enough fuel for them to get from one gas station to the next.<\/p>\n<p>Unless, of course, you drive an SUV. <\/p>\n<p>Anyway, it\u2019s amazing the lengths that people will go to just to receive a miniscule reward. Some people will sit in line for hours just to get $40 worth of gas; others will write scripts that can pick computer names out of a text file, just to get a measly little paycheck and to listen to people tell them, \u201cYou know, we absolutely <i>love<\/i> what you\u2019re doing. In fact, we love it so much we\u2019d like you to stop doing it and do something completely different.\u201d<\/p>\n<p>Not that we know anyone like that, mind you. As it turns out, a \u2026friend \u2026 of ours put together the following script, a script that can pick computer names out of a text file:<\/p>\n<pre class=\"codeSample\">Const ForReading = 1\n\nSet objFSO = CreateObject(\"Scripting.FileSystemObject\")\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n\nDo Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\n    intLength = Len(strLine)\n    If intLength &gt; 39 Then   \n        strSubString = Right(strLine, intLength - 36)\n        arrSubString = Split(strSubString, \" \")\n        If arrSubString(1) = \"failed\" Then\n            Wscript.Echo arrSubString(0)\n        End If\n    End If\nLoop\n\nobjFile.Close\n<\/pre>\n<p>Before we explain how this script works let\u2019s take a look at the kind of text file DA has to deal with (OK, we\u2019re guessing this isn\u2019t <i>exactly<\/i> like the text DA has to deal with, but it\u2019s close enough):<\/p>\n<pre class=\"codeSample\">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxatl-ws-001 failed to respond.\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxatl-fileserver-002 failed to install software.\nxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxredmond-dc-003 succeeded.\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxlondon-printserver-001 failed to respond.\n<\/pre>\n<p>As you can see in lines 1, 2, and 5 we have 36 characters (as indicated by the 36 x\u2019s) followed by the name of a computer (a name that can be of any length) followed by a blank space and the word <i>failed<\/i>. These are the only three lines in the file that we care about. Why don\u2019t we care about line 3? That\u2019s easy: it has less than 40 characters. And what about line 4? Well, line 4 meets the minimum length requirements, and it <i>does<\/i> have a computer name beginning at character position 37. However, that computer name isn\u2019t followed by the word <i>failed<\/i>. That\u2019s why we don\u2019t care about line 4.<\/p>\n<table class=\"dataTable\" id=\"ECE\" 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>. OK, that\u2019s a little harsh: the truth is, the Scripting Guys care about each and every line in each and every text file in the world. We just have no immediate use for line 4, as much as we might \u2013 and do \u2013 care about it.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>OK, so how are we going to pick out the desired lines and, more important, extract the computer name? Well, to begin with, we define a constant named ForReading and set the value to 1; we\u2019ll need to use this constant when we open our text file. After defining the constant we create an instance of the <b>Scripting.FileSystemObject<\/b>, then use the following line of code, and the <b>OpenTextFile<\/b> method, to open the file C:\\Scripts\\Test.txt for reading:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n<\/pre>\n<p>Once the file is open we set up a Do Until loop designed to run until we\u2019ve read each and every line in the file. (Or, if you\u2019re a stickler for technical accuracy, until the file\u2019s <b>AtEndOfStream<\/b> property is True.) Inside that loop we use the <b>ReadLine<\/b> method to read a line from the file and store that value in a variable named strLine:<\/p>\n<pre class=\"codeSample\">strLine = objFile.ReadLine\n<\/pre>\n<p>That means that, the first time through the loop, strLine will be equal to this:<\/p>\n<pre class=\"codeSample\">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxatl-ws-001 failed to respond.\n<\/pre>\n<p>What good does that do us? Well, to tell you the truth, not a whole lot. So let\u2019s see what we can do about that.<\/p>\n<p>To begin with, we need to verify that strLine contains at least 40 characters. We can easily determine the number of characters in strLine by using the <b>Len<\/b> function:<\/p>\n<pre class=\"codeSample\">intLength = Len(strLine)\n<\/pre>\n<p>So <i>does<\/i> strLine contain at least 40 characters? Beats the heck out of us. But this line of code will tell us:<\/p>\n<pre class=\"codeSample\">If intLength &gt; 39 Then\n<\/pre>\n<p>So what happens if intLength is <i>not<\/i> greater than 39? Nothing (literally): in that case we simply go back to the top of the loop and try again with the next line in the text file. If the length of the string <i>is<\/i> greater than 39 we then run this line of code:<\/p>\n<pre class=\"codeSample\">strSubString = Right(strLine, intLength - 36)\n<\/pre>\n<p>What are we doing here? Well, we know that the computer name begins at character position 37; therefore, we can make our scripting life much easier if we simply discard the first 36 characters. That\u2019s what this line of code is intended to do. In this line we\u2019re using the <b>Right<\/b> function to start at the end of the string and, moving backwards, take the next <i>x<\/i> number of characters. And what is <i>x<\/i> supposed to be equal to? As it turns out, x is equal to the total number of characters in the string minus 36. For example, if strLine contains 65 characters we\u2019ll take 29 characters: 65 \u2013 36. And what happens if we start at the end of the string and, working backwards, take the next 29 characters? That\u2019s effectively going to chop off the first 36 characters in strLine, leaving us with this:<\/p>\n<pre class=\"codeSample\">atl-ws-001 failed to respond.\n<\/pre>\n<p>Now we\u2019re getting somewhere, eh? And guess what? We\u2019ll get even farther after we execute <i>this<\/i> line of code:<\/p>\n<pre class=\"codeSample\">arrSubString = Split(strSubString, \" \")\n<\/pre>\n<p>What we\u2019re doing here is using the <b>Split<\/b> function to split strLine into an array, creating a new array item each time we encounter a blank space (\u201c \u201c). What will that give us? That will give us an array with the following elements:<\/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>atl-ws-001 <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>failed <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>to <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>respond.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>So what\u2019s next? Well, next we check to see if the second item in the array (the item with the index number 1) is equal to the word <i>failed<\/i>:<\/p>\n<pre class=\"codeSample\">If arrSubString(1) = \"failed\" Then\n<\/pre>\n<p>If it\u2019s not, then this is another line we aren\u2019t concerned with; as you might recall, we\u2019re looking for a computer name followed by the word <i>failed<\/i>. If the second item in the array doesn\u2019t equal <i>failed<\/i> we simply go back to the top of the loop and try again with the next line in the file.<\/p>\n<p>Now, what if the second item in our array <i>is<\/i> the world <i>failed<\/i>? Well, in that case, the first item in the array (index number 0) must be the name of a computer where something failed. How do we extract the computer name? That\u2019s <i>really<\/i> easy; we simply echo back the value of the first item in the array:<\/p>\n<pre class=\"codeSample\">Wscript.Echo arrSubString(0)\n<\/pre>\n<p>And then, again, it\u2019s back to the top of the loop, where we repeat the process with the next line in Test.txt.<\/p>\n<p>When we\u2019ve finished reading all the lines in the file we call the <b>Close<\/b> method and call it a day. In turn, we should see a report similar to this onscreen:<\/p>\n<pre class=\"codeSample\">atl-ws-001\natl-fileserver-002\nlondon-printserver-001\n<\/pre>\n<p>And yes, that <i>is<\/i> just exactly what we hoping to see. Thanks for asking!<\/p>\n<p>We think that should do the trick, DA; let us know if you have any further questions. In the meantime, the Scripting Guy who writes this column is intrigued by the large number of people who were attracted to the Great Gas Giveaway. As a matter of fact, he\u2019s so intrigued that <i>[<\/i><i>Ed<\/i><i>itor\u2019s Note: Please <\/i><i>disregard<\/i><i> everything in the article from this point on. The Scripting Guy who writes this column is delusional again.]<\/i> he\u2019s offering $100 of free gas to everyone who visits the Script Center during the month of June! Come visit the Script Center in June: it\u2019s a great way to learn about system administration scripting, and an even better way to get free gas! See you all back here in June!<\/p>\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>. Has the Scripting Guy who writes this column figured out where he\u2019s going to get all that gas, and how he\u2019s going to pay for it? Well, no, not exactly; as the Scripting Editor points out \u2013 two or three times a day \u2013 planning isn\u2019t really his forte. But how much could that be, anyway? After all, each month the Script Center attracts about 450,000 unique visitors; at $100 per visitor, that comes out to about $45 million. Do the Scripting Guys really have enough money in their budget to buy $45 million worth of gas during the month of June? Well, you would <i>think<\/i> so, wouldn\u2019t you? Nevertheless, he\u2019ll have to double-check that. In the meantime, you might want to go easy on the gas, and maybe even take the bus or something. You know, just in case he\u2019s mistaken about the budget.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a text file containing thousands of events. I need to read each line in that file and look for the name of the computer where an operation failed. The computer names can \u2013 and will \u2013 vary in length; however, the name will always begin in character position 37, and [&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-55493","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 containing thousands of events. I need to read each line in that file and look for the name of the computer where an operation failed. The computer names can \u2013 and will \u2013 vary in length; however, the name will always begin in character position 37, and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55493","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=55493"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55493\/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=55493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}