2

I've got thousands of files in a specific directory and sub directories.

  • C:\Food\
  • C:\Food\Avocado.sln (also contains the string "Avocado")
  • C:\Food\Avocado.DataModel\
  • C:\Food\Avocado.DataModel\AvocadoModel.cs (also contains the string "Avocado")

I'd like to replace all instances of the string "Avocado" with "Burger" in the directory namess, file names and file content e.g.

  • C:\Food\
  • C:\Food\Burger.sln (all intances of "Avocado in file contents now changed to "Burger")
  • C:\Food\Burger.DataModel\
  • C:\Food\Burger.DataModel\BurgerModel.cs (all intances of "Avocado in file contents now changed to "Burger")

I'd like to do this using Powershell.

How can I do this?

2
  • What file types to check, only .sln and .cs? Only check files in folders containing Avocado or general? Only check files for content avocado when it's also in file name or all? Commented Aug 12, 2017 at 9:13
  • @LotPings all files. i'm learning how to use powershell at the moment so posted my answer below. i am sure there are other (better) ways to achieve what i want. i also realise that there might be issues with my solution when my directory conatins binary files (so for my situation i removed the \bin and \obj directories) Commented Aug 12, 2017 at 9:35

2 Answers 2

2

I used the script below to change the directory names, file names and file contents. I understand there might be easier ways to do this using the pipe | operator but this makes sense to me at the moment (I'm relatively new to Powershell).

# change these three variables to suit your requirements
$baseDirectory = "C:\Food\"
$a = "Avocado"
$b = "Burger"

# get all files
$files = Get-ChildItem $baseDirectory -File -Recurse
# get all the directories
$directorys = Get-ChildItem $baseDirectory -Directory -Recurse

# replace the contents of the files only if there is a match
foreach ($file in $files)
{
    $fileContent = Get-Content -Path $file.FullName

    if ($fileContent -match $a)
    {
        $newFileContent = $fileContent -replace $a, $b
        Set-Content -Path $file.FullName -Value $newFileContent
    }
}

# change the names of the files first then change the names of the directories

# iterate through the files and change their names
foreach ($file in $files)
{
    if ($file -match $a)
    {
        $newName = $file.Name -replace $a, $b
        Rename-Item -Path $file.FullName -NewName $newName
    }
}

# reverse the array of directories so we go deepest first
# this stops us renaming a parent directory then trying to rename a sub directory which will no longer exist
# e.g.
# we might have a directory structure "C:\Rename\Rename"
# the file array would be [ C:\Rename, C:\Rename\Rename ]
# without reversing we'd rename the first directory to "C:\NewName"
# the directory structure would now be "C:\NewName\Rename"
# we'd then try to rename C:\Rename\Rename which would fail
[array]::Reverse($directorys)

# iterate through the directories and change their names
foreach ($directory in $directorys)
{
    if ($directory -match $a)
    {
        $newName = $directory.Name -replace $a, $b
        Rename-Item -Path $directory.FullName -NewName $newName
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

I wouldn't even try to edit potentially binary files,
so the following script processes only specified file types
and for security does a backup.

$baseDirectory = "C:\Food\"
$a = "Avocado"
$b = "Burger"
$Include = '*.sln','*.cs'


Pushd $baseDirectory

# process all file and  directory names 
Get-ChildItem -Filter "*$a*" -Recurse|
  Rename-Item -NewName {$_.Name -replace $a,$b} -confirm


Get-ChildItem -Include $Include -Recurse | ForEach-Object{
  if (Select-String -Path $_ -Pattern $a -quiet){
    $BakName = "{0}.bak" -f $_.FullName
    $OldName = $_.FullName
    $_ | Move-Item -Destination $BakName -force
    (Get-Content $BakName) -replace $a,$b | Set-Content $OldName
  }
}
PopD

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.