«

»

Aug 24 2016

Bulk Rename Files with RegExp

Renaming a file is a common task for which Windows Explorer is enough. However, when it comes to to bulk renaming files things are not so simple. For instance, How-to-Geek describes how to bulk rename files with Windows Explorer and the Command Line, but admits that these are very limited and lacking flexibility. The same article also explains how to accomplish the task using Powershell’s Rename-Item commandlet, which gives the user much more power and flexibility, but the user must master its somewhat complex syntax. So we can conclude that, when it comes to bulk renaming files, these are not necessarily the best options. Hence it seems that incorporating renaming tools to our routine practices, such as the Bulk Rename Utility or Renameit!, is unavoidable. It is, of course, also possible to design a custom-tailored RenameFiles routine or function, as shown below.

The function signature is:

Function RenameFiles(ByVal strPattern, ByVal strReplace, ByVal strRoot, ByVal boolSearchAll)

Where:

  1. strPattern is a valid regular expression pattern.
  2. strReplace is the text string to replace the match.
  3. strRoot is the root folder to begin with.
  4. boolSearchAll is a boolean that indicates whether to perform the operation recursively or not. The default is False.

Warning notes:

  • The function is recursive if the boolSearchAll argument is True; that is, it searches for files matching the RegExp.Pattern in the root folder and all the subfolders it contains at all levels. For this reason it is strongly recommended to pass boolSearchAll as False (or empty, since the default is False) unless you know exactly what you are trying to do.
  • The function performs a Move operation, so beware that your search pattern does not make all files get the same name with the replace string. For instance, if you have 10 files named MyFile_[variable timestamp here].txt, your search pattern is \d\d\d\d_\d\d_\d\d_\d\d_\d\d_\d\d and your replace string is MyNewString, then all file names will get the name MyFile_MyNewString.txt and only one (the first) will be actually renamed, which is not the desired result.
Function RenameFiles(ByVal strPattern, ByVal strReplace, ByVal strRoot, ByVal boolSearchAll)
    On Error ResumeNext
 
    Dim FSO
    Dim objRoot, objFolder, objSubFolders
    Dim objFiles, objFile
    Dim strFolderName
    Dim regex
    Dim strNewFileName
 
    '--- Validate the arguments
    If(IsEmpty(strPattern) Or strPattern = "")Then Exit Function
    If(IsEmpty(strReplace) Or strReplace = "")Then Exit Function
    If(IsEmpty(strRoot) Or strRoot= "")Then Exit Function
    '--- Default value (False)
    If(IsEmpty(boolSearchAll) Or boolSearchAll = "")Then boolSearch = False
 
    Set regex = New RegExp
    regex.Pattern = strPattern
 
    Set FSO =CreateObject("Scripting.FileSystemObject")
    Set objRoot = FSO.GetFolder(strRoot)    
 
    '--- Handle recursive search and rename
    If(boolSearchAll)Then
        Set objSubFolders = objRoot.SubFolders
        ForEach objFolder In objSubFolders    
            Call RenameFiles(strPattern, strReplace, objFolder.Path, boolSearchAll)
 
            Set objFiles = objFolder.Files
            If Err.Number <>0Then'To handle access denied errors and the like
                WScript.Echo("ERROR: "& Err.Number &" | "& Err.Description &" | "& Err.Source)
            EndIf
            strFolderName = objFolder.Path
            ForEach objFile In objFiles
    	    	If(regex.Test(objFile.Name))Then
                    strNewFileName = regex.Replace(objFile.Name, strReplace)
                    WScript.Echo("Renaming: "& strFolderName &"\"& objFile.Name &" to "& strNewFileName)            
                    Call FSO.MoveFile(strFolderName &"\"& objFile.Name, strFolderName &"\"& strNewFileName)
    	    	End If                   
            Next
        Next
    End If
 
    '--- Handle search and rename in the root folder
    strFolderName = objRoot.Path
    Set objFiles = objRoot.Files
    ForEach objFile In objFiles
    	If(regex.Test(objFile.Name))Then
		strNewFileName = regex.Replace(objFile.Name, strReplace)
	        WScript.Echo("Renaming: " & strFolderName & "\" & objFile.Name & " to " & strNewFileName)
	        Call FSO.MoveFile(strFolderName & "\" & objFile.Name, strFolderName & "\" & strNewFileName)        
	End If    
    Next
    
    Set FSO =Nothing
EndFunction

Usage

Call RenameFiles(".*MyOldString.*\.txt", "MyNewString", "C:\Users\johndoe\Documents", True) 'Recursively rename all files
Call RenameFiles(".*MyOldString.*\.txt", "MyNewString", "C:\Users\johndoe\Documents", False) 'Rename just the files in the root folder
Call RenameFiles(".*MyOldString.*\.txt", "MyNewString", "C:\Users\johndoe\Documents", "") 'Rename just the files in the root folder
Call RenameFiles(".*MyOldString.*\.txt", "MyNewString", "C:\Users\johndoe\Documents", Empty) 'Rename just the files in the root folder

About Meir Bar-Tal

Meir Bar-Tal is an Automation Architect with extensive technical, educational and leadership experience in Software Design, Development and Testing. For many years Meir has helped companies establish solid foundations for their testing activities with a wide variety of software applications and systems and across different technologies and platforms. Meir is a well-known expert in Data-Driven, Keyword Driven and Hybrid methodologies and has published a number of influential articles on the applications of Design Patterns to Test Automation. For the last five years, he has been pushing forward an ambitious program towards the development of an Object Oriented automation framework named Sunscrit, a huge project which is still underway. Meir is the owner of www.AdvancedQTP.com of which he was a co-founder in 2007 and served as its Editor in Chief, Author and Forums Administrator ever since. Meir lives in Israel and cooperates closely with HP R&D and other colleagues to improve the user experience and productivity with HP Software tools.