I'm attempting to do a simple find and replace using the Powershell Get-Content and Set-Content commands. In the Powershell terminal, I am calling the following expression:
(Get-Content test_file.yml) | ForEach-Object { $_ -replace 'foo', 'bar' } | Set-Content test_file.yml
This replaces the instances of "foo" with "bar" in my test_file.yml exactly as I expect. I'm running into problems when I attempt to call this command from within a batch file. Here is an example of how I am calling it in a batch file:
@echo off
@REM copying file to make updates
copy original_file.yml test_file.yml
@REM Text to be updated
set "NEW_TEXT="bar"
@REM replacing text in the file
powershell -Command "& { (Get-Content test_file.yml) | ForEach-Object { $_ -replace 'foo', '%NEW_TEXT%' } | Set-Content test_file.yml }"
When I call the command like this, I get the error:
'Set-Content' is not recognized as an internal or external command, operable program or batch file.
I've searched through lots of forums and other stack overflow questions and can't seem to figure out where I'm going wrong. I'm very new to writing windows batch files so any help would be appreciated.
Your problem is this line:
set "NEW_TEXT="bar"
There is a quote too much. That puts the pipe|
in front of set-content
technically outside of quoting, which doesn't give it to Powershell, but is interpreted by the cmd
interpreter, meaning the following is a batch command. set-content
isn't.
Switch to this format:
set "NEW_TEXT=bar"
Note: this is the preferred syntax, the quotes make it safe against stray tailing spaces, but are not included into the variable. You usually quote the string where needed (as you did with Powershell syntax '
), not where defined