A Windows Shell Script To Automatically Rename And Move Images To A New Folder

Recently asked on Yahoo! Answers:

How do I set Windows XP to rename same named files when in same directory?
I’m putting thousands of images and other files in the same folder so that I can sort from that folder, I want to keep all the versions that I may have the same file name with different names when I put them in that folder. If I can I would also like to leave the () out of the new rename. I’ve seen other computers that do the renaming automatically, this would save me time from the current setting in which it asks with each file if I want to overwrite it and if it doesn’t overwrite it just leaves the file where it was before without putting it in!

This is simple enough to do if you have a little knowledge of VBScript; in this case, as it pertains to the Windows Scripting Host (or whatever Microsoft calls it these days).

Basically, a few lines of VBS can quickly get all the files in a directory, maintain their current sort order, rename them to be 100 percent unique, and move those files from whatever directory they are currently in to wherever we want them to go.

Let’s do it. As always, code you can download appears at the end of this listing.

Some important notes about this solution before we get into the code proper:

  • This script only works for files that end in .jpg or .jpeg (case-insensitive). It won’t rename / move other image types.
  • This script is not recursive. It deals only with files in the specified source directory, not with the subdirectories or the files in any subdirectories. You need to change the source folder path and continue running this script for all subdirectories.
  • Images are moved from the source directory to the destination directory.
  • Images are permanently renamed in this format: YYYYMMDDhhmm_X (that is, today’s year, month, day, hour, minute, an underscore, and a padded image number.
  • There is no way for two images to have the same name with this system.
  • Images are sorted in this script in alphanumeric order before processing, so that sets may be renamed in their original order.
    • The Files collection — which is the most convenient way to go about getting all the files in a given folder — does not return file names in a specific order and there is no way to work directly with the collection to reorder it.
    • If we want an explicit sort, we must do so with an intermediary array. More on that shortly.

We’ll start by declaring the source and destination directory variables, which you need to change to match the file paths for the directories you want to use. Note that all file paths must end with a trailing slash!

'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'DO NOT CHANGE THE LINE BELOW!
Dim SourcePath, DestinationPath
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

'################################################################################################
'CHANGE THE PATH VARIABLES BELOW to match your source / destination folders!
'Folder paths MUST have trailing slashes!

SourcePath = "C:testinput"
DestinationPath = "C:testoutput"
'################################################################################################

That’s all the user changes the script needs. Now, to the nuts & bolts.

We start with some variables, including the basic pattern of the new file name:

'Variables
Dim I, Y, strName, FileCount, ZeroPad, strTemp
strName = CStr(Year(Now)) & CStr(Month(Now)) & CStr(Day(Now)) & CStr(Hour(Now)) & CStr(Minute(Now)) & "_"

'FSO variables
Dim objFSO, objInput, objOutput, objFile

With variables out of the way, we can create the FileSystemObject, then the source folder, and get a count of the files in the source folder:

'create FSO
Set objFSO = CreateObject("Scripting.FileSystemObject")

'Open source folder
Set objInput = objFSO.GetFolder(SourcePath)

'Compute size of file name
FileCount = Len(CStr(objInput.Files.Count))

We need to declare an array that will contain all the image file names in the source folder, so that we can later sort the files alphanumerically:

'Declare array to hold file names
Dim theFiles()
ReDim theFiles(objInput.Files.Count)

We need to initialize a short string with zeros, so that our newly named files will follow the same alphanumeric sorting rules we’re trying to preserve with the array.

For example, if there are 234 images in the folder, we want to name them 001 to 234. To do that, we will create a string with three zeros, and later, we’ll use that three-zero string to pad out the current image number.

'Create padding for file rename
For I = 1 To FileCount
	ZeroPad = ZeroPad & "0"
Next

'Reset I
I = 0

With the preliminaries out of the way, we can go through each file in the folder.

If it’s an image file — a fact we establish by looking for the file extension .jpg or .jpeg in the file name — we add it to the array we declared earlier. After we go through the entire list, we reset the array size to be the same as the number of items it contains.

'Process all files in folder
For Each objFile In objInput.Files
    'if file has JPG or JPEG extension, add to files array
    If InStr(1, objFile.Name, ".jpg", 1) > 0 Or InStr(1, objFile.Name, ".jpeg", 1) > 0 Then
	    theFiles(I) = objFile.Name
	    I = I + 1
    End If
Next
ReDim Preserve theFiles(I)

Now, we bubble sort the array, to maintain alphanumeric order:

'bubble sort files array
For I = (UBound(theFiles) - 1) To 0 Step -1
    For Y = 0 To I
        If UCase(theFiles(Y)) > UCase(theFiles(Y + 1)) Then
            strTemp = theFiles(Y + 1)
            theFiles(Y + 1) = theFiles(Y)
            theFiles(Y) = strTemp
        End If
    Next
Next

'Reset I
I = 1

And now, we simply iterate through the array, renaming the files it contains and moving them to the destination folder:

'Rename and move files
For Each strTemp In theFiles
    If objFSO.FileExists(SourcePath & strTemp) Then
	    objFSO.MoveFile SourcePath & strTemp, DestinationPath & strName & Right(ZeroPad & I, FileCount) & ".jpg"
	    I = I + 1
	End If
Next

A little cleanup, and a message telling us how many items were moved from where to where, just to let us know the script is done:

'Clean up objects
Set objFile = Nothing
Set objInput = Nothing
Set objFSO = Nothing

'Report script complete
MsgBox("Processing completed for " & SourcePath & ". Renamed and moved " & UBound(theFiles) & " image files to " & DestinationPath & ".")

That’s it.

2 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • Check out the Commenting Guidelines before commenting, please!
  • Want to share code? Please put it into a GitHub Gist, CodePen or pastebin and link to that in your comment.
  • Just have a line or two of markup? Wrap them in an appropriate SyntaxHighlighter Evolved shortcode for your programming language, please!