{"id":67343,"date":"2006-05-11T09:42:00","date_gmt":"2006-05-11T09:42:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/05\/11\/how-can-i-rename-files-using-file-names-ive-written-to-a-text-file\/"},"modified":"2006-05-11T09:42:00","modified_gmt":"2006-05-11T09:42:00","slug":"how-can-i-rename-files-using-file-names-ive-written-to-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-rename-files-using-file-names-ive-written-to-a-text-file\/","title":{"rendered":"How Can I Rename Files Using File Names I\u2019ve Written to a Text File?"},"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 bunch of files with names like 001.jpg and 002.jpg. I also have a text file that includes the names I would <I>like<\/I> each of these files to have; for example, 001.jpg should be named Picture_of_Family_Members.jpg. How can I write a script that reads information from the text file and then renames each picture accordingly?<BR><BR>&#8212; RG<\/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, RG. You know, one day Paul Simon was in a Chinese restaurant when he noticed that one of the selections on the menu was \u201cChicken With Egg.\u201d Duly inspired, a short time later he wrote the classic song <I>Mother and Child Reunion<\/I>. As Casey Stengal said, you can look it up.<\/P>\n<P>Now, no doubt you\u2019re wondering what this has to do with your question. To tell you the truth, we have no idea; it\u2019s just a piece of trivia we\u2019ve always found interesting. <\/P>\n<P>And no, it never <I>did<\/I> occur to us that other people might not find it so interesting. We\u2019ll have to think about that a bit.<\/P>\n<P>While we ponder that possibility, here\u2019s a little something that might be a bit more relevant to your question:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>strComputer = &#8220;.&#8221;\nset objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;c:\\scripts\\names.txt&#8221;, ForReading)<\/p>\n<p>Do Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\n    arrParts = Split(strLine, &#8220;,&#8221;)\n    strFile = &#8220;C:\\\\Pictures\\\\&#8221; &amp; arrParts(0)\n    Set colItems  = objWMIService.ExecQuery _\n        (&#8220;Select * From CIM_Datafile Where Name = &#8216;&#8221; &amp; strFile &amp; &#8220;&#8216;&#8221;)\n    For Each objItem in colItems\n        strNewName = &#8220;C:\\Pictures\\&#8221; &amp; arrParts(1)\n        objItem.Rename strNewName\n    Next\nLoop<\/p>\n<p>objFile.Close\n<\/PRE>\n<P>Before we go any further we should note that this script is perhaps a tad bit more complicated than needed; had we chosen to use the FileSystemObject to rename the files we could have cut down on both the number of lines of code as well as the cryptic nature of some of those lines. So then why <I>didn\u2019t<\/I> we use the FileSystemObject? Well, we wanted a script that could rename the files even if those files were stored on a remote computer. Because the FileSystemObject isn\u2019t designed for remote operations, that left us with WMI as the technology of choice. And that\u2019s both good and bad. The good part? This script can easily be modified to work against a remote machine. The bad part? You have to be willing to put up with an eccentricity or two when it comes to locating and renaming files using WMI.<\/P>\n<P>As for the code itself, we start out by defining a constant named ForReading and setting the value to 1; we\u2019ll use this constant later on to open the text file for reading (as opposed to opening it for writing or for appending). We then use these lines of code to connect to the WMI service on the local computer:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;\nset objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)\n<\/PRE>\n<TABLE id=\"EOD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. What\u2019s that? Connect to the WMI service on a remote machine? We never said &#8211; oh, that\u2019s right: we <I>did<\/I> say something about using this script against remote machines, didn\u2019t we? Well, that\u2019s easy enough: just set the value of the variable strComputer to the name of the remote machine. For example, this line of code will cause the script to connect to (and thus rename the files on) a remote computer named atl-fs-01:<\/P><PRE class=\"codeSample\">strComputer = &#8220;atl-fs-01&#8221;\n<\/PRE><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Next we need to open our text file. Here we use &#8211; well, what do you know: the <B>FileSystemObject<\/B>. Like we said, we don\u2019t want to use this object to rename the files; however, it\u2019s about our only recourse when it comes to reading a text file. With that in mind, these two lines of code create the FileSystemObject and then use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Names.txt for reading:<\/P><PRE class=\"codeSample\">Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;c:\\scripts\\names.txt&#8221;, ForReading)\n<\/PRE>\n<P>Now let\u2019s roll up our sleeves and get to work. We\u2019re assuming your text file looks something like this, with the current file name listed first and the preferred file name listed second:<\/P><PRE class=\"codeSample\">001.jpg,Picture_of_Family_Members.jpg\n002.jpg,At_the_Airport.jpg\n003.jpg,Our-Hotel.jpg\n<\/PRE>\n<P>With the file open we set up a Do Until loop that will simply read the file in line-by-line until there is nothing left to read. (Or, if you want to impress all your friends and neighbors, reads the file line-by-line until the <B>AtEndOfStream<\/B> property is true.) To do that, we start out by reading the first line in the file and storing the value in a variable named strLine:<\/P><PRE class=\"codeSample\">strLine = objFile.ReadLine\n<\/PRE>\n<P>That means that strLine is equal to this:<\/P><PRE class=\"codeSample\">001.jpg,Picture_of_Family_Members.jpg\n<\/PRE>\n<P>And <I>that<\/I> means we need to separate the current file name from the preferred file name. Can we do that? Heck no. But the VBScript <B>Split<\/B> function can:<\/P><PRE class=\"codeSample\">arrParts = Split(strLine, &#8220;,&#8221;)\n<\/PRE>\n<P>What the Split function does is examine a string and chop it into separate pieces, placing each piece in an array we named arrParts. How does the function know where to make each chop? That\u2019s easy: the second parameter passed to Split (\u201c,\u201d) tells the function to make a chop every time it encounters a comma. With the first line read in from the text file that means we\u2019ll end up with an array consisting of two items:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>001.jpg<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Picture_of_Family_Members.jpg<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Because the first item in a VBScript array always has the index number 0, we now know two things: item 0 &#8211; or arrParts(0) &#8211; represents the current file name, and item 1 &#8211; arrParts(1) &#8211; represents the desired file name.<\/P>\n<P>And once we know that we can better understand what this line of code does:<\/P><PRE class=\"codeSample\">strFile = &#8220;C:\\\\Pictures\\\\&#8221; &amp; arrParts(0)\n<\/PRE>\n<P>In a moment we\u2019re going to use WMI to connect to the file C:\\Pictures\\001.jpg, the first file listed in the text file and the first file to be renamed. What we\u2019re doing here is creating the full path to the file, something we do by combining <B>C:\\\\Pictures\\\\<\/B> and the name of the file (which, as we know, is item 0 in our array). <\/P>\n<P>Good question: why <I>do<\/I> we have \\\\\u2019s in the path? Well, we\u2019re going to use this path in a WMI query and, as it turns out, the \\ is a reserved character in WMI. The only way to use a reserved character in a WMI query is to \u201cescape\u201d it; that is, to preface it with a \\. As you can probably guess, a \\ prefaced with another \\ gives us a \\\\. It\u2019s crucial that we escape each \\ in the path. (And, yes, if we were dealing with a UNC path like \\\\atl-fs-01\\public we\u2019d have to convert it to this: \\\\\\\\atl-fs-01\\\\public. What a strange and wonderful world we live in.)<\/P>\n<P>Speaking of WMI queries, here\u2019s the one we use to connect to the file 001.jpg:<\/P><PRE class=\"codeSample\">Set colItems  = objWMIService.ExecQuery _\n    (&#8220;Select * From CIM_Datafile Where Name = &#8216;&#8221; &amp; strFile &amp; &#8220;&#8216;&#8221;)\n<\/PRE>\n<P>All we\u2019re doing with this line of code is asking WMI to return a collection of files that have the <B>Name<\/B> C:\\Pictures\\001.jpg (although, for the purposes of the query, we have to call it this C:\\\\Pictures\\\\001.jpg). Because path names must be unique (you can\u2019t have two files named C:\\Pictures\\001.jpg) we can rest assured that this query will bind us to the desired file.<\/P>\n<P>Another good question: what if the file C:\\Pictures\\001.jpg doesn\u2019t exist? That\u2019s fine; in that case our collection will simply be a collection with 0 items in it. In turn, the script will skip the section of code that loops through the collection and instead simply go off and read in the next line from the text file.<\/P>\n<P>In case you\u2019re wondering, the section of code that loops through the collection looks like this:<\/P><PRE class=\"codeSample\">For Each objItem in colItems\n    strNewName = &#8220;C:\\Pictures\\&#8221; &amp; arrParts(1)\n    objItem.Rename strNewName\nNext\n<\/PRE>\n<P>We already know that, at most, we\u2019re going to have a single item in the collection: the file 001.jpg. That means we can go ahead and rename the file. To do that we first construct a new file path, a path consisting of <B>C:\\Scripts<\/B> plus the new file name (which, as you recall, is item 1 in our array):<\/P><PRE class=\"codeSample\">strNewName = &#8220;C:\\Pictures\\&#8221; &amp; arrParts(1)\n<\/PRE>\n<P>At that point we call the <B>Rename<\/B> method, passing the variable strNewName as the sole parameter:<\/P><PRE class=\"codeSample\">objItem.Rename strNewName\n<\/PRE>\n<P>And then it\u2019s back to the beginning of the loop, where we repeat the process with the next line in the text file.<\/P>\n<P>Admittedly, this might seem a bit complicated. But all we\u2019re really doing is this:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Reading a line from a text file.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Picking out the existing file name and the new file name.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Connecting to the existing file.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Renaming the existing file.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>See? It\u2019s really not all that bad after all. <\/P>\n<P>Anyway, we hope that helps, RG. Right now we have to go look up more baseball and rock and roll trivia. You know, people here at Microsoft don\u2019t appreciate all the hard work and research that goes into writing a column like this one \u2026.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a bunch of files with names like 001.jpg and 002.jpg. I also have a text file that includes the names I would like each of these files to have; for example, 001.jpg should be named Picture_of_Family_Members.jpg. How can I write a script that reads information from the text file 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":[38,3,4,12,14,5],"class_list":["post-67343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-files","tag-scripting-guy","tag-scripting-techniques","tag-storage","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have a bunch of files with names like 001.jpg and 002.jpg. I also have a text file that includes the names I would like each of these files to have; for example, 001.jpg should be named Picture_of_Family_Members.jpg. How can I write a script that reads information from the text file and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67343","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=67343"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67343\/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=67343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}