Reputation: 5281
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
I need to make this change each time someone runs our program.
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
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
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:
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