{"id":66493,"date":"2006-09-12T13:51:00","date_gmt":"2006-09-12T13:51:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/09\/12\/how-can-i-identify-the-last-file-in-a-sequential-list-of-files\/"},"modified":"2006-09-12T13:51:00","modified_gmt":"2006-09-12T13:51:00","slug":"how-can-i-identify-the-last-file-in-a-sequential-list-of-files","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-identify-the-last-file-in-a-sequential-list-of-files\/","title":{"rendered":"How Can I Identify the Last File in a Sequential List of Files?"},"content":{"rendered":"<p><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\"> \n<P>Hey, Scripting Guy! I have a folder which contains thousands of files, all numbered sequentially. How can I tell which file is the last file in the list?<BR><BR>&#8212; AC<\/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, AC. You know, one of the fun things about being a Scripting Guy is that we get to spend a lot of time shattering myths. For example, when we first started at Microsoft there was a myth that system administrators had no interest in (or aptitude for) scripting and automation. Shattered! Likewise it was a well-accepted \u201cfact\u201d that WMI was way too difficult for script writers to learn. Shattered! Today we tackle yet another well-entrenched myth: if you want to do something right then you should work hard while doing it.<\/P>\n<P>Need we say it? Shattered!<\/P>\n<TABLE id=\"E3C\" 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>. Technically, the Scripting Guys have nothing against hard work. As long as we don\u2019t have to any of it, well, what difference does it make to us?<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>As you noted, AC, you have a folder that contains thousands of files, each having a name similar to this:<\/P><PRE class=\"codeSample\">200500001.pdf\n200500002.pdf\n200500003.pdf\n200500004.pdf\n&#8230;\n200509999.pdf\n<\/PRE>\n<P>In the example above, file 200509999.pdf is the last file in the sequential list. The question is, how do you <I>know<\/I> that? How can you write a script that can identify the last file in a sequential list of files?<\/P>\n<P>As you might expect, the Scripting Guy who writes this column took one look at this question and immediately came up with a solution. Of course, it was a complicated and convoluted solution, and our hero knew it would take some real effort to create the script and then write the column that explained how the script worked. But was the prospect of a little hard work enough to scare off the Scripting Guy who writes this column? You better believe it was.<\/P>\n<P>In fact, instead of rolling up his sleeves and getting down to work, the Scripting Guy who writes this column found all sorts of other things to do, things which he hadn\u2019t thought about in months but which suddenly became high-priority, must-do items. But here\u2019s the moral of the story: being lazy turned out to be a <I>good<\/I> thing. Had he been the earnest, hard-working type, the Scripting Guy who writes this column would have come up with a script that would have been far more complicated than it needed to be. By contrast, shirking his responsibilities for awhile gave him time to realize that this problem could be solved in far-easier fashion, and without resorting to arrays, bubble sorts, and several eyes of newt, all of which were required in his initial solution. Being lazy turned into a win-win situation: the Scripting Guy who writes this column didn\u2019t have to work very hard, and you ended up with a script that\u2019s short, sweet, and to the point.<\/P>\n<P>In other words, a script that looks like this:<\/P><PRE class=\"codeSample\">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:\\PDFs&#8217;} Where &#8221; _\n        &amp; &#8220;ResultClass = CIM_DataFile&#8221;)<\/p>\n<p>For Each objFile In colFileList\n    strFile = objFile.FileName\nNext<\/p>\n<p>Wscript.Echo strFile\n<\/PRE>\n<P>So how did our hero almost turn such a simple script into a nightmarish morass of code? Well, the problem was that he thought about it too hard. He knew that, in order to determine which file comes last in the list he would need to sort the files by file name. He also knew that once the files were sorted he had to be able to identify the very last file in the alphabetical list. Determined to make a mountain out of a molehill, he immediately envisioned a solution involving arrays, disconnected recordsets, and an army of highly-trained St. Bernards, none of which were actually needed.<\/P>\n<P>So why <I>weren\u2019t<\/I> they needed? Two reasons. First, there\u2019s no need to sort the files by file name; if you use WMI to retrieve the files they will, by default, already come sorted by file name. Had he acted on his first impulse, the Scripting Guy who writes this column would have written some fancy-schmancy code whose sole purpose was to sort a collection that was already sorted. That seemed a tad bit silly, even for a Scripting Guy.<\/P>\n<P>Second, it\u2019s true that we need to identify the last file in the collection. And, admittedly, we could do that by storing all the files in an array, using the Ubound function to identify the last item in that array, and then echoing back the value of that last item. But, again, that\u2019s way more work than we need to put in. We already have a collection of pre-sorted files; instead of adding all those files in an array, why not just quickly rifle through the collection? As soon as we run out of files we\u2019ll know which one is the last file in the list: that\u2019ll be the file we just finished looking at.<\/P>\n<P>And so that\u2019s exactly what we do. This far-simpler script begins by connecting to the WMI service on the local computer (although it could just as easily perform this same task on a remote computer). We then use this crazy-looking <B>Associators of<\/B> query to return a collection of all the files in the folder C:\\PDFs:<\/P><PRE class=\"codeSample\">Set colFileList = objWMIService.ExecQuery _\n    (&#8220;ASSOCIATORS OF {Win32_Directory.Name=&#8217;C:\\PDFs&#8217;} Where &#8221; _\n        &amp; &#8220;ResultClass = CIM_DataFile&#8221;)\n<\/PRE>\n<P>Note that we\u2019re assuming that all the files in this folder have been named using the sequential-numbering scheme. If there are other files in this folder you\u2019ll need to modify your For Each loop to discard files that aren\u2019t part of the target collection<\/P>\n<P>Speaking of For Each loops, that\u2019s our next step: we set up a For Each loop to walk through the collection of files, files \u2013 we might add \u2013 that are already sorted for us by file name (first 200500001.pdf, then 200500002.pdf, etc.). Notice that, inside the loop, we only do one thing: we assign the <B>FileName<\/B> of the current file to a variable named strFile:<\/P><PRE class=\"codeSample\">strFile = objFile.FileName\n<\/PRE>\n<P>Why do we do that? Well, let\u2019s say we have three files in the collection. The first time through the loop strFile will be assigned the name of the first file in the collection (2000500001.pdf). The second time through the loop, strFile gets assigned the name of the second file in the collection (200500002.pdf). And \u2013 oh, you\u2019re way ahead of us, aren\u2019t you? Yes, the third and final time through the loop strFile gets assigned the name of the third file in the collection. At that point we exit the loop, with strFile equal to 200500003.pdf.<\/P>\n<P>Believe it or not that <I>is<\/I> a big deal. We\u2019re looking for the name of the last file in the sequence, right? Well, guess what: we just found it. The last file we looked at is also the last file in the sequence; to get our answer all we have to do is echo back the value of strFile:<\/P><PRE class=\"codeSample\">Wscript.Echo strFile\n<\/PRE>\n<P>It\u2019s not fancy, but it does the trick, and \u2013 best of all \u2013 it does it with a minimum amount of effort. And it\u2019s reasonably fast, too: we tried it with 5,000 files in a folder and the script completed its work in less than 15 seconds. That was good enough for us.<\/P>\n<P>Of course, we should point out that this script works only because your naming system includes leading zeroes in the file names. Unfortunately, this script will <I>not<\/I> work if you have file names similar to this:<\/P><PRE class=\"codeSample\">20056.pdf\n20057.pdf\n20058.pdf\n20059.pdf\n200510.pdf\n<\/PRE>\n<P>Why not? Because these names are going to be sorted alphabetically and not numerically, which means they\u2019ll be sorted like this:<\/P><PRE class=\"codeSample\">200510.pdf\n20056.pdf\n20057.pdf\n20058.pdf\n20059.pdf\n<\/PRE>\n<P>Unfortunately, the script will identify file 20059.pdf as the last file in the sequence, which is definitely not the case. But we shouldn\u2019t blame the script; type <B>dir c:\\pdfs<\/B> and the files will be sorted in the same fashion: alphabetic rather than numeric.<\/P>\n<P>So is it possible to deal with file names that don\u2019t include leading zeroes? Yes, although that would require quite a bit of effort, and you already know how the Scripting Guys feel about hard work and effort. But if that\u2019s something you <I>really<\/I> need to know, drop us a line and we\u2019ll see what we can do. We\u2019ll start resting up, just in case.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a folder which contains thousands of files, all numbered sequentially. How can I tell which file is the last file in the list?&#8212; AC Hey, AC. You know, one of the fun things about being a Scripting Guy is that we get to spend a lot of time shattering myths. [&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":[715,38,3,12,5],"class_list":["post-66493","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-associators-of","tag-files","tag-scripting-guy","tag-storage","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have a folder which contains thousands of files, all numbered sequentially. How can I tell which file is the last file in the list?&#8212; AC Hey, AC. You know, one of the fun things about being a Scripting Guy is that we get to spend a lot of time shattering myths. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66493","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=66493"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66493\/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=66493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=66493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=66493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}