Search code examples
c#stringwinformsdirectory

How to Rename FolderNames and FileNames with matching strings Recursively


My application generates files in the following directory structure

FolderMatchALeve1
-FileMatchALevel2_A.cs
-FileMatchALevel2_B.cs
-FolderMatchALevel2
--FileMatchALevel3_A.txt
--FileMatchALevel3_B.txt

I am looking for a way to rename the directory structure, with the following change – Change “MatchA” to “AMatch”.

So the result should look like so after executing the program:

FolderAMatchLeve1
-FileAMatchLevel2_A.cs
-FileAMatchLevel2_B.cs
-FolderAMatchLevel2
--FileAMatchLevel3_A.txt
--FileAMatchLevel3_B.txt

So far in my quest to find a solution, I have been unsuccessful. Please help me find a solution to this.

I need this solution in C# Winforms because of maintaining a legacy product at our company.

Edit:

Additional Information

  1. I need to make this change each time someone runs our program.

  2. I need to do this to 3350 files

Question Summary:

In short, while recursively(or iteratively) going through each directory, I want it to rename files whose names match with matching strings and then after coming out, rename the directory, if it too has a name matching the string (for all partial or complete matches).


Solution

  • Quick and Dirty (but working)

    public static class DirectoryRenamer
    {
        public static void RenameDirectoryTree( string path, Func<string, string> renamingRule )
        {
            var di = new DirectoryInfo( path );
            RenameDirectoryTree( di, renamingRule );
        }
    
        public static void RenameDirectoryTree( DirectoryInfo directory, Func<string, string> renamingRule )
        {
            InternalRenameDirectoryTree( directory, renamingRule );
    
            var currentName = directory.Name;
            var newName = renamingRule( currentName );
            if ( currentName != newName )
            {
                var newDirname = Path.Combine( directory.Parent.FullName, newName );
                directory.MoveTo( newDirname );
            }
        }
    
        static void InternalRenameDirectoryTree( DirectoryInfo di, Func<string, string> renamingRule )
        {
            foreach ( var item in di.GetFileSystemInfos() )
            {
                var subdir = item as DirectoryInfo;
                if ( subdir != null )
                {
                    InternalRenameDirectoryTree( subdir, renamingRule );
    
                    var currentName = subdir.Name;
                    var newName = renamingRule( currentName );
                    if ( currentName != newName )
                    {
                        var newDirname = Path.Combine( subdir.Parent.FullName, newName );
                        subdir.MoveTo( newDirname );
                    }
                }
    
                var file = item as FileInfo;
                if ( file != null )
                {
                    var currentName = Path.GetFileNameWithoutExtension( file.Name );
                    var newName = renamingRule( currentName );
                    if ( currentName != newName )
                    {
                        var newFilename = Path.Combine( file.DirectoryName, newName + file.Extension );
                        file.MoveTo( newFilename );
                    }
                }
            }
        }
    }
    

    sample usage

    class Program
    {
        static void Main( string[] args )
        {
            DirectoryRenamer.RenameDirectoryTree( 
                @"C:\Test\FolderMatchALevel", 
                name => name.Replace( "MatchA", "AMatch" ) );
        }
    }