I need to find and replace one occurrence of a string in a PowerShell script (script is about 250 lines long). There are two occurrences where the string "start-sleep -s 10" appears within the script. I need to edit and only change the first occurrence to "start-sleep -s 30 and keep the second occurrence "start-sleep -s 10". The issue I'm having is that there are a couple variants of the script I have to edit so my approach was locate the range of lines where the first occurrence is located, make the change, then save the script and keep everything else as is. New to PowerShell so not sure how to go about this. I keep seeing articles online of how to use Get-Content and Set-Content to find and replace text in a file but I need to change the first occurrence of "start-sleep -s 10" and keep the second one as is. Here is what I have so far:
$ScriptPath = "C:\ScriptsFolder\powershell.ps1"
$scriptcontent = (Get-Content $ScriptPath)
$var1 = "Start-Sleep -s 10"
$var2 = "Start-Sleep -s 30"
$var3 = $scriptcontent | Select-Object -Index (0..250) | Select-String -Pattern $var1 |
Select-Object -First 1
$var3 -replace $var1 , $var2 | Set-Content $ScriptPath
What I get isn't what I'm looking for, I'm able to make the change on the line but when I set the content it overwrites the whole file and keeps just the 1 start sleep line I edited. Any help would be awesome
CodePudding user response:
For this you can read the file line-by-line and once you encounter the first match of what you're looking for, set a variable that can be used in case of future matches of the same word.
I would personally recommend you to use a switch
with the -File
parameter to efficiently read the file. See inline comments for details on the code's logic.
$ScriptPath = "C:\ScriptsFolder\powershell.ps1"
$newContent = switch -Wildcard -File $ScriptPath {
# if this line contains `Start-Sleep -s 10`
'*Start-Sleep -s 10*' {
# if we previously matched this
if($skip) {
# output this line
$_
# and skip below logic
continue
}
# if we didn't match this before (if `$skip` doesn't exist)
# replace from this line `Start-Sleep -s 10` for `Start-Sleep -s 30`
$_.Replace('Start-Sleep -s 10', 'Start-Sleep -s 30')
# and set this variable to `$true` for future matches
$skip = $true
}
# if above condition was not met
Default {
# output this line as-is, don't change anything
$_
}
}
$newContent | Set-Content $ScriptPath