Home > Enterprise >  How to find and replace all substrings from a list of known files in Powershell?
How to find and replace all substrings from a list of known files in Powershell?

Time:09-27

I am replace the name of variable in configuration files. I already know where the files are among the thousands of other files and don't need to bother looking through all directories. Each config file can have more than one instance of this substring that needs to be replaced. I have the script like so:

$search = "Initial Catalog=db"
$replace = "Initial Catalog=newdb"
$base = "C:\Users\Administrator\"
$known_locations = @(
    $base   "admin\config.config",
    $base   "www\web.config",
)

But I've been stuck for too long and trying multiple ways without success. The files never get set with the new strings and I'm not sure why this doesn't work.

$known_locations | ForEach-Object {
    (Get-Content $_ | ForEach-Object {$_ -replace $search, $replace}) | Set-Content $_
}

Upon inspection in the debugger in vscode, the replace doesn't find the substrings and I wonder if it has to do with the types of strings, single quotes vs double quotes, or something else I'm not understanding.

CodePudding user response:

Assuming both locations actually exist and the files are there, then the issue with your code is how you're defining the array, the comma should not be there, it's creating a one element array with a string concatenating both values:

$known_locations = @(
    $base   "admin\config.config",
    $base   "www\web.config"
)

PS ..\> $known_locations[0]
C:\Users\Administrator\admin\config.config C:\Users\Administrator\www\web.config

PS ..\> $known_locations[0].GetType()

IsPublic IsSerial Name         BaseType
-------- -------- ----         --------
True     True     String       System.Object

This works for me using test files, I would also recommend you to use a literal string replacement method and -Raw for efficiency.

$known_locations = @(
    $base   "admin\config.config"
    $base   "www\web.config"
)

$known_locations | ForEach-Object {
    (Get-Content $_ -Raw).Replace($search, $replace) | Set-Content $_
}
  • Related