{"id":64793,"date":"2007-05-24T23:14:00","date_gmt":"2007-05-24T23:14:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/05\/24\/how-can-i-compare-the-contents-of-two-text-files\/"},"modified":"2007-05-24T23:14:00","modified_gmt":"2007-05-24T23:14:00","slug":"how-can-i-compare-the-contents-of-two-text-files","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-compare-the-contents-of-two-text-files\/","title":{"rendered":"How Can I Compare the Contents of Two Text Files?"},"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! I have two separate text files. One file contains a list of MAC addresses taken from a network scan; the other contains a list of MAC addresses for our currently-managed devices. How can I compare these two files, and output a list of addresses that have no corresponding device to a third text file?<BR><BR>&#8212; SR <\/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, SR. You know, last night the Scripting Guy who writes this column was watching TV when \u2013 hey, get out of here! Shoo! Shoo! Go on, get out!<\/P>\n<P>Sorry; the goats wandered through the office again. We really need to put a door on this building, don\u2019t we?<\/P>\n<P>Anyway, last night the Scripting Guy who writes this column was watching TV when a segment about the NBA draft came on. As it turns out, in the NBA draft lottery the Portland Trailblazers drew the first pick in the draft and the Seattle Supersonics drew the second pick. No big deal, right?<\/P>\n<P>Wrong, at least according to commentator Stephen A. Smith. Smith was absolutely outraged by this turn of events, labeling it a black day for the NBA. \u201cYou\u2019ve got the two most exciting prospects to come around in years headed for the NBA,\u201d he fumed. \u201cAnd now both of them are going to end up in the Pacific Northwest, where no one will ever see them!\u201d<\/P>\n<P>Well, needless to say, the Scripting Guy who writes this column was outraged by Stephen A. Smith. What, we don\u2019t have civilization up here in the Pacific Northwest? To tell you the truth, his first thought was to pick up the phone, call Stephen A. Smith, and give him what-for. And he would have, too \u2026 assuming we actually <I>had<\/I> telephones in the Pacific Northwest.<\/P>\n<TABLE class=\"dataTable\" id=\"EDD\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P><B>Note<\/B>. In case you\u2019re wondering, Stephen A. Smith hails from Philadelphia. The fact of the matter is that we hicks out here in the Pacific Northwest can\u2019t hold a candle to someone from Philadelphia.<\/P>\n<P>Mainly because we don\u2019t actually <I>have<\/I> candles in the Pacific Northwest. But someday .\u2026<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>At any rate, on behalf of the entire Pacific Northwest, the Scripting Guys would like to apologize to everyone who still cares about the NBA. (Yes, both of you.) And we\u2019d like to make it up to everyone. Granted, those of us in the Pacific Northwest might not have fancy, modern-day conveniences like wall-to-wall carpeting and frozen yogurt, but we <I>do<\/I> have scripts that can compare two text files and report back any differences:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile1 = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Current.txt&#8221;, ForReading)<\/p>\n<p>strCurrentDevices = objFile1.ReadAll\nobjFile1.Close<\/p>\n<p>Set objFile2 = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Addresses.txt&#8221;, ForReading)<\/p>\n<p>Do Until objFile2.AtEndOfStream\n    strAddress = objFile2.ReadLine\n    If InStr(strCurrentDevices, strAddress) = 0 Then\n        strNotCurrent = strNotCurrent &amp; strAddress &amp; vbCrLf\n    End If\nLoop<\/p>\n<p>objFile2.Close<\/p>\n<p>Wscript.Echo &#8220;Addresses without current devices: &#8221; &amp; vbCrLf &amp; strNotCurrent<\/p>\n<p>Set objFile3 = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Differences.txt&#8221;)<\/p>\n<p>objFile3.WriteLine strNotCurrent\nobjFile3.Close\n<\/PRE>\n<TABLE class=\"dataTable\" id=\"EZD\" 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>. We apologize for using a stylus to inscribe today\u2019s column into a stone tablet. Unfortunately that\u2019s the best we can do out in the God-forsaken wasteland we call the Pacific Northwest. We hope this doesn\u2019t inconvenience anyone. And it shouldn\u2019t, provided your firewall will allow stone tablets to pass through.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>All right, let\u2019s see if we can figure out how this script works. (Needless to say, we have to do that right away, before the sun goes down.) To begin with, we have a text file named C:\\Scripts\\Current.txt, which lists the MAC addresses for all our currently-managed devices. That file looks something like this:<\/P><PRE class=\"codeSample\">00:14:A5:4D:AC:01\n00:14:A5:4D:AC:03\n00:14:A5:4D:AC:04\n<\/PRE>\n<P>We also have a second text file (C:\\Scripts\\Addresses.txt), which lists all the MAC addresses acquired during a network scan:<\/P><PRE class=\"codeSample\">00:14:A5:4D:AC:01\n00:14:A5:4D:AC:02\n00:14:A5:4D:AC:03\n00:14:A5:4D:AC:04\n00:14:A5:4D:AC:05\n<\/PRE>\n<P>What we want to do is compare the two files and see if there are devices on the network (identified using the MAC address) that do not appear in our list of currently-managed devices. In other words, we want to generate a list of unmanaged\/unknown devices. So, what the heck: let\u2019s go ahead and generate such a list.<\/P>\n<P>Hey, drop that! Drop it, I say!<\/P>\n<P>Sorry; raccoons tried to walk off with our text files again. Dirty, low-down, no-good varmints \u2026.<\/P>\n<P>In the script itself we start out by defining a constant named ForReading; we\u2019ll need this constant to open and read from our two text files. We next create an instance of the <B>Scripting.FileSystemObject<\/B>, then use this line of code to open the file C:\\Scripts\\Current.txt for reading:<\/P><PRE class=\"codeSample\">Set objFile1 = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Current.txt&#8221;, ForReading)\n<\/PRE>\n<P>From there we use the <B>ReadAll<\/B> method to read in the entire file, storing the contents in a variable named strCurrentDevices. And then, with no further need for Current.txt, we use the <B>Close<\/B> method to close the file.<\/P>\n<P>We now have a list of the MAC addresses for all our managed devices. Our next step is to get the list of all MAC addresses found on the network and then check each of those addresses, one-by-one, to see if they show up in the list of managed devices.<\/P>\n<P>To that end, the first thing we do is open the file C:\\Scripts\\Addresses.txt, also for reading:<\/P><PRE class=\"codeSample\">Set objFile2 = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Addresses.txt&#8221;, ForReading)\n<\/PRE>\n<P>Because each MAC address is listed on a separate line in the file, we set up a Do Until loop that will run until we reach the end of the file. (Or, to be a little more technical, until the <B>AtEndOfStream<\/B> property is True.) Inside that loop, we use the <B>ReadLine<\/B> method to read the first line in the file (that is, the first MAC address) and store that value in a variable named strAddress:<\/P><PRE class=\"codeSample\">strAddress = objFile2.ReadLine\n<\/PRE>\n<P>Using our sample file, that means strAddress is equal to this:<\/P><PRE class=\"codeSample\">00:14:A5:4D:AC:01\n<\/PRE>\n<P>That brings us to this line of code:<\/P><PRE class=\"codeSample\">If InStr(strCurrentDevices, strAddress) = 0 Then\n<\/PRE>\n<P>What we\u2019re doing here is using the <B>InStr<\/B> function to determine whether or not the first MAC address (00:14:A5:4D:AC:01) can be found anywhere in the list of managed devices. As you can see, InStr takes two parameters: the string we want to search (strCurrentDevices) and the string we\u2019re searching for (strAddress). InStr returns the character position at which the search string is found; if the search string <I>can\u2019t<\/I> be found then InStr returns 0.<\/P>\n<P>In other words, if InStr returns 0 that means that the address is <I>not<\/I> in the list of managed devices. Therefore, we add that address to a running tally of unmanaged devices:<\/P><PRE class=\"codeSample\">strNotCurrent = strNotCurrent &amp; strAddress &amp; vbCrLf\n<\/PRE>\n<P>That bit of code is fairly straightforward: all we\u2019re doing is assigning a value to a variable named strNotCurrent. And what value are we assigning this variable? We\u2019re assigning it the existing value of strNotCurrent <I>plus<\/I> the MAC address we just failed to find (strAddress) <I>plus<\/I> a carriage return-linefeed (vbCrLf). And then we loop around and repeat this process with the next MAC address.<\/P>\n<P>When we\u2019ve finished checking all the MAC addresses we close the file, then use this line of code to echo back the results:<\/P><PRE class=\"codeSample\">Wscript.Echo &#8220;Addresses without current devices: &#8221; &amp; vbCrLf &amp; strNotCurrent\n<\/PRE>\n<P>Based on our sample text files, that\u2019s going to result in the following information appearing onscreen:<\/P><PRE class=\"codeSample\">Addresses without current devices:\n00:14:A5:4D:AC:02\n00:14:A5:4D:AC:05\n<\/PRE>\n<P>And then, because SR wanted to save the results to a third file, we then execute this final block of code:<\/P><PRE class=\"codeSample\">Set objFile3 = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Differences.txt&#8221;)<\/p>\n<p>objFile3.WriteLine strNotCurrent\nobjFile3.Close\n<\/PRE>\n<P>What we\u2019re doing here is first creating a new text file, one named C:\\Scripts\\Differences.txt. Once the file has been created we then call the <B>WriteLine<\/B> method to write the value of strNotCurrent to the new file. After that we close the file and call it good.<\/P>\n<P>Of course, you could just as easily go the other direction and search for managed devices that don\u2019t appear in the list of addresses. To accomplish that feat all you have to do is first read in the list of addresses and then search that list for each managed device. (Exactly the opposite of the task we just finished.) That code would look something like this:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile1 = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Addresses.txt&#8221;, ForReading)<\/p>\n<p>strAddresses = objFile1.ReadAll\nobjFile1.Close<\/p>\n<p>Set objFile2 = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Current.txt&#8221;, ForReading)<\/p>\n<p>Do Until objFile2.AtEndOfStream\n    strCurrent = objFile2.ReadLine\n    If InStr(strAddresses, strCurrent) = 0 Then\n        strNoAddress = strNoAddress &amp; strCurrent &amp; vbCrLf\n    End If\nLoop<\/p>\n<p>objFile2.Close<\/p>\n<p>Wscript.Echo &#8220;Devices with no address: &#8221; &amp; vbCrLf &amp; strNoAddress<\/p>\n<p>Set objFile3 = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Differences.txt&#8221;)<\/p>\n<p>objFile3.WriteLine strNoAddress\nobjFile3.Close\n<\/PRE>\n<P>Needless to say, you could also combine these two scripts and end up looking for items that appear in File A but not in File B as well as items that appear in File B but not in File A. But we\u2019ll let you take care of that yourself.<\/P>\n<P>We hope that answers your question, SR. In the meantime, we Scripting Guys are getting ready to watch Stephen A. Smith\u2019s TV show and \u2013 oh, wait a minute. Sorry, we forgot: Stephen A. Smith\u2019s TV show was cancelled. What a shame, huh?<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have two separate text files. One file contains a list of MAC addresses taken from a network scan; the other contains a list of MAC addresses for our currently-managed devices. How can I compare these two files, and output a list of addresses that have no corresponding device to a third [&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-64793","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 two separate text files. One file contains a list of MAC addresses taken from a network scan; the other contains a list of MAC addresses for our currently-managed devices. How can I compare these two files, and output a list of addresses that have no corresponding device to a third [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64793","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=64793"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64793\/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=64793"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64793"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}