Vikas Gupta
Vikas Gupta

Reputation: 10904

Powershell: Error while replacing the sub-string in a file

I am trying to replace some of the sub-strings with some values across multiple files. I have written this code to do so.

$dirPath = 'C:\repos\sync_cpc_cva\ExpressV2\Parameters\AG08\KeyVault'
$ConfigPath = 'C:\repos\sync_cpc_cva\config.json'

$lookupTable = @{}
(Get-Content -Raw -Path $configPath | ConvertFrom-Json).psobject.properties | Foreach { $lookupTable[$_.Name] = $_.Value }

Get-ChildItem -Path $dirPath -Recurse -Filter *.json | 
Foreach-Object {
    
    Get-Content $_.FullName | ForEach-Object {
        $line = $_
        
        $lookupTable.GetEnumerator() | ForEach-Object {
            
            if($line -match $_.Key) {
                
                $line = $line -replace $_.Key, $_.Value
                
            }
        }
        $line
    } | Set-Content -Path $_.FullName
}

If I print the content, it has replaced all the values correctly, however, it is unable to set the contents into the same file. And I am getting following error while running the code :

Set-Content : The process cannot access the file
'C:\repos\sync_cpc_cva\ExpressV2\Parameters\AG08\KeyVault\KeyVault.USNat.json' because it is being used by another process.
At C:\repos\sync_cpc_cva\filltest.ps1:22 char:9
+     } | Set-Content -Path $_.FullName
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Set-Content], IOException
    + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand

Any idea how can I replace the sub-strings in the same file?

Upvotes: 0

Views: 217

Answers (1)

Farbkreis
Farbkreis

Reputation: 644

You have several inner foreach-object loops, so you modify the $_ operator while being used. I dont think this can work. Revolve it like this:

$lookupTable = @{}
(Get-Content -Raw -Path $configPath | ConvertFrom-Json).psobject.properties | Foreach { $lookupTable[$_.Name] = $_.Value }

$files = Get-ChildItem -Path $dirPath -Recurse -Filter *.json

foreach ($file in $files) {
    $content = Get-Content $file.FullName
    for($i=0;$i -lt $content.length; $i++) {
        $lookupTable.GetEnumerator() | ForEach-Object {
            $content[$i] = $content[$i] -replace $_.Key, $_.Value
        }

    }
    $content | Set-Content $file.FullName

}



Upvotes: 1

Related Questions