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).

Upvotes: 0

Views: 1023

Answers (2)

Sir Rufo
Sir Rufo

Reputation: 19096

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" ) );
    }
}

Upvotes: 1

Christopher
Christopher

Reputation: 9804

Using wildcards I was once able to change the file-endings of a number of files using basic move command. But these changes might be a bit beyond it.

But overall this is just trivial recursion over folders using Directory Class or one of the other ones. Pseudo code goes like this:

  1. List all Directories in the current directory.
  2. Recursively call this function again for all the sub-directories
  3. Iterate over all the files in this directory
  4. Rename this directory.

Note that the "proper" way to do renaming is the move command. Indeed there is no technical difference between move and rename on the same disk.

You also may want to put Nr. 4 on a Boolean Switch. Name one of the Parameters "DirectoryRename". Let it default to true. Hand it in false on the first call and do not use it for recursive calls.

Upvotes: 1

Related Questions