Quick and Dirty C# Recursive Find and Replace

Say you had a vast Visual Studio solution of something ridunculous like 120+ projects and wanted to test out a few proofs of concept on improving build times.

Now say that one of the proofs of concept was to use a shared bin folder for all projects in a single solution. Editing 120+ proj files is going to make you a little crazy.

How about a little recursive find-and-replace app using regular expressions (my saviour in many menial text manipulation tasks) to do it all for you? That’d be nice, wouldn’t it? That’s what I thought too. So I just did a quick and dirty console app to do just that.

[csharp]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections.ObjectModel;

namespace RecursiveFindAndReplace
{
class Program
{
static void Main(string[] args)
{
// where to start your directory walk
var directoryToTraverse = @"C:\VisualStudio2010\Projects\TestSolutionWithLoadsOfProjectsInIt\";

// what files to open
var fileTypeToOpen = "*.csproj";

// what to look for
var patternToMatch = @"<OutputPath>bin\\[a-zA-Z]*\\</OutputPath>;";
var regExp = new Regex(patternToMatch);
// the new content
var patternToReplace = @"<OutputPath>;C:\bin\$(Configuration)\</OutputPath>";

// get all the files we want and loop through them
foreach (var file in GetFiles(directoryToTraverse, fileTypeToOpen))
{
// open, replace, overwrite
var contents = File.ReadAllText(file);
var newContent = regExp.Replace(contents, patternToReplace);
File.WriteAllText(file, newContent);
}
}

// recursive method to return the files we want in all sub dirs of the initial root
static List<string> GetFiles(string directoryPath, string extension)
{
var fileList = new List<string>();
foreach (var subDir in Directory.GetDirectories(directoryPath))
{
fileList.AddRange(GetFiles(subDir, extension));
}

fileList.AddRange(Directory.GetFiles(directoryPath, extension));

return fileList;
}

}
}[/csharp]

No doubt this could be made prettier with a little lambda, but like I said – quick and dirty.

—————–

Edit: I’ve just realised that Directory.GetFiles is inherently recursive. Duh. So the foreach instead becomes:

[csharp highlight=”4″]// get all the files we want and loop through them
foreach (var file in Directory.GetFiles(directoryToTraverse
,fileTypeToOpen
,SearchOption.AllDirectories))
{
// open, replace, overwrite
var contents = File.ReadAllText(file);
var newContent = regExp.Replace(contents, patternToReplace);
File.WriteAllText(file, newContent);
}[/csharp]

So that’s even quicker and slightly less dirty. Ah well.

Leave a Reply

Your email address will not be published. Required fields are marked *