I am writing a script changing the memory value within a configuration file. I want to search for a set specific set of lines within this file, and I tried using PowerShell to do the job.
It works fine for a single line replace, but trying to match across multiple lines does not produce results. The script is as follows
A section of the config that I am trying to parse is below:
{
"taskType": "BuildDynamicMPLSCloud",
"version": 1,
"subTasks": [],
"execName": "BuildDynamicMPLSCloud",
"execCategory": 1
"maximumMemory": 4294967296
},
{
"taskType": "BuildDynamicMap",
"version": 1,
"subTasks": [],
"execName": "BuildDynamicMap",
"execCategory": 1,
"maximumMemory": 4294967296
},
Testing against one line to find and replace works:
$NewContent=Get-Content "C:\Program Files\NetBrain\Worker Server\conf\rmworker.json" | ForEach-Object { $_-replace """maximumMemory"": 4294967296", """execName"": ""BuildDynamicMap"",`r`n`t ""execCategory"": 1,`r`n`t ""maximumMemory"": 8589934592" }
Set-Content -Path "C:\Program Files\NetBrain\Worker Server\conf\rmworker.json" -Value $NewContent
The output from above code is as shown below:
{
"taskType": "BuildDynamicMPLSCloud",
"version": 1,
"subTasks": [],
"execName": "BuildDynamicMPLSCloud",
"execCategory": 1
"execName": "BuildDynamicMap",
"execCategory": 1,
"maximumMemory": 8589934592
},
{
"taskType": "BuildDynamicMap",
"version": 1,
"subTasks": [],
"execName": "BuildDynamicMap",
"execCategory": 1,
"execName": "BuildDynamicMap",
"execCategory": 1,
"maximumMemory": 8589934592
},
But when attempting to match multiple lines for the same replace script does not succeed:
$NewContent=Get-Content "C:\Program Files\NetBrain\Worker Server\conf\rmworker.json" | ForEach-Object { $_-replace """execName"": ""BuildDynamicMap"",`r`n`t ""execCategory"": 1,`r`n`t ""maximumMemory"": 4294967296" , """execName"": ""BuildDynamicMap"",`r`n`t ""execCategory"": 1,`r`n`t ""maximumMemory"": 8589934592" }
Set-Content -Path "C:\Program Files\NetBrain\Worker Server\conf\rmworker.json" -Value $NewContent
At the start of each newline there is 1 tab and 2 spaces within the config file.
If you want to use -Replace
the following will work:
$NewContent = (Get-Content "C:\Program Files\NetBrain\Worker Server\conf\rmworker.json" -Raw) -replace "(?ms)""execName"": ""BuildDynamicMap"",.*?""execCategory"": 1,.*?""maximumMemory"": 4294967296" , """execName"": ""BuildDynamicMap"",`r`n`t""execCategory"": 1,`r`n`t""maximumMemory"": 8589934592"
I used the -Raw
switch to return the file contents as one string. This removes the need to treat each line individually with a Foreach-Object
command. In the regex part of the replace, I removed the linefeed and tab items in favor of .*?
. I used the singleline and multiline modifiers (?sm
) because the string is multiple lines and I want the .
regex character to match new line characters. Your regex string also had an extra space after the "maximumMemory":
that I removed.
I left your replacement string as is, which will have an issue with spacing. You'll notice the extra two space indention. You may not want to use tab in your replacement or fix the other lines to align to tab.