-1

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.

5
  • Please note: I've changed your title and removed one tag. You original tags and title were confusing: when you mention batch file, .cmd or .bat file is assumed, and it has nothing to do with PowerShell. Moreover, the term PowerShell is self-consistent, no need to mention Windows. Commented Aug 1 at 14:42
  • 1
    Stephan posted the solution for this syntax mistake. If you want to know more about " on definition of an environment variable, read Why is no string output with 'echo %var%' after using 'set var = text' on command line? Best on having a string value assigned to an environment variable in a batch file which later runs PowerShell using this string value is accessing the environment variable string value with PowerShell itself, i.e. replace '%NEW_TEXT%' by $Env:NEW_TEXT. Commented Aug 1 at 15:27
  • Please read the PowerShell documentations pages about_Environment_Variables and about_Operators and about_Quoting_Rules. Commented Aug 1 at 15:28
  • @SergeyAKryukov "powershell" itself does not imply that the host platform is windows. Commented Aug 10 at 21:26
  • @starball — Ah, yes, agree. It's just that batch file assumes that it is about Windows, and the inquirer mistake was in the batch file, not in the PowerShell script. Commented Aug 11 at 21:34

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

Comments

1

This is corrected 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 }"

Everything works now.

You problem was in the set command. It should be as it is now.

Also, you may want to add the check and make sure the file to be copied exists (if exists). It's a quesion if you want to overwrite the resulting file, but, logically, it should be fine.

Finally, you don't need @REM, as @echo off already disabled echo of the comments.

Comments

-1

With a quick search you should be able to find a distribution of GNU utilities for Windows.

As a specific tool for your use case I would suggest the Windows compiled version of sed. https://www.gnu.org/software/sed/sed.html

The full list of GNU utilities (https://www.gnu.org/software/software.html) includes many other desirable utilities, such as bash, coreutils, emacs, gawk, gcc, grep, groff, sed, tar, wdiff, and wget.

2 Comments

Why do you suggest using sed from the GNU utilities if the original poster asked for help on a PowerShell command line executed from within a Windows batch file? That does not answer the question at all. Sure, sed can be used to search and replace a string in a text file, but PowerShell can do that too and must not be extra installed on Windows 10/11.
While the question DOES indicate that they are trying to accomplish this in PowerShell, the real issue is trying to replace specific content. The questioner indicated having issues in PowerShell, particularly with the get-content and set-content directives. In this case, sed is a viable, lightweight alternative that can be invoked within PowerShell.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.