Often when I'm working on solutions I have a lot of projects that are all pretty much starting from the same place as another. For example, "unit test project targeting .net5, with FluentAssertions, Moq, Autofixture" - but also sometimes projects with a similar class structures too like a "repository that talks to MongoDB, with an ISomethingConfig", or a "Lambda with DI container". Of course I could create Visual Studio templates for these, but often templates fall out of date or I'd end up still needing to copy in some specific classes from a recently used project that I want to replicate. In a lot of cases I found myself copying and pasting and entire project folder, renaming the files accordingly then going through the csproj/cs files to replace the namespace and/or class names to target my "new" project. To automate this I wrote a Bash script, which might not be the most elegant or robust script in the world, but it does the job so I thought I'd share it here:

# Script to create a new Visual Studio project folder from an existing one
# Usage: ./csprojclone.sh Your.Namespaced.Source Your.Namespaced.Destinationn

if [ $# -lt 2 ]
	then
		echo "Please pass source and destination namespace arguments"
		return -1
fi
source=${1%%/}
dest=${2%%/}

if [[ ! -d $source ]]
	then
		echo "Source directory does not exist or isn't a folder - make sure you are in the correct working directory"
		return -1
fi

if [[ -e $dest ]]
        then
                echo "Destination folder already exists in the working directory"
                return -1
fi

oldproject=${source%%.UnitTests}
oldproject=${oldproject##*.}
newproject=${dest%%.UnitTests}
newproject=${newproject##*.}

cp -r $source $dest
rm -r $dest/bin/
rm -r $dest/obj/
find $dest -iname "*$source*" -exec rename -v "s/$source/$dest/" {} \;
find $dest -iname "*$oldproject*" -exec rename -v "s/$oldproject/$newproject/" {} \;
find $dest -type f -print0 | xargs -0 sed -i "s/$source/$dest/g"
find $dest -type f -print0 | xargs -0 sed -i "s/$oldproject/$newproject/g"
As per the script, the usage is to call the script from within your solution directory, passing in the name of the existing project folder and then a destination one. The script will clone the source, rename the files, search and replace the namespace change and update any classes that had the specific project name in. If you're using it on a unit tests project, it will strip of ".UnitTests" from the path - so if that's not your naming convention then feel free to edit those bits. Here's an example of how it might work: PWD = /path/to/SolutionFolder
    My.Namespace.UserRepository 
    My.Namespace.UserRepository/My.Namespace.UserRepository.csproj
    My.Namespace.UserRepository/MongoStuff/...
    My.Namespace.UserRepository/IUserRepositoryConfig.cs
    etc..

. /path/to/script/csprojclone.sh My.Namespace.UserRepository My.Namespace.OrderRepository
Will create:
    My.Namespace.OrderRepository
    My.Namespace.OrderRepository/My.Namespace.OrderRepository.csproj
    My.Namespace.OrderRepository/MongoStuff/...
    My.Namespace.OrderRepository/IOrderRepositoryConfig.cs
With all namespaces also updated.