3

This command works to replace instances of OldText1, OldText2 and OldText3 in a txt file, with NewText1, NewText2 and NewText3 when the command is on one line in a batch file like so:

start /wait /min Powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Get-ChildItem 'Old and New text.txt' | ForEach-Object {(Get-Content $_) -replace 'OldText1', 'NewText1' -replace 'OldText2', 'NewText2' -replace 'OldText3', 'NewText3' | Set-Content $_.FullName}"

If I try to use the ^ symbol to split the command up (that typically works in a batch file) it doesn't work. For example this doesn't work, nothing is replaced in the txt file:

start /wait /min Powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Get-ChildItem 'Old and New text.txt' | ForEach-Object {(Get-Content $_) ^
-replace 'OldText1', 'NewText1' ^
-replace 'OldText2', 'NewText2' ^
-replace 'OldText3', 'NewText3' ^
| Set-Content $_.FullName}"

Using backticks also doesn't work (but it wouldn't because this is not a PS1 script):

start /wait /min Powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Get-ChildItem 'Old and New text.txt' | ForEach-Object {(Get-Content $_) `
-replace 'OldText1', 'NewText1' `
-replace 'OldText2', 'NewText2' `
-replace 'OldText3', 'NewText3' `
| Set-Content $_.FullName}"

I have been asking that chat bot thing all morning and it can't come up with anything that works. Half the time it keeps putting the command on one line again and I'm just going around in circles with it.

Is it impossible to do what I am trying to do?

The reason I want to split the command over multiple lines is simply because I want to be able to read what's being replaced without having to look horizontally along (what will eventually be) a massive command. I intend to add far more replace commands than this, but it's not working even for three replace commands... yet!

Thanks in advance to anyone that might know why this isn't working.

3
  • Try to use the caret syntax, but enclose each line in its own double-quotes (").
    – harrymc
    Commented Feb 11, 2023 at 15:15
  • Thanks but that won't work.
    – bat_cmd
    Commented Feb 11, 2023 at 15:58
  • 1
    See also: this SO post.
    – mklement0
    Commented Oct 6, 2023 at 21:24

1 Answer 1

1

This is not clear to me:

Get-ChildItem 'Old and New text.txt' | ForEach-Object {(Get-Content $_)

This part suggests that you are going to get items in a folder, precisely items that are files, but immediately your command defines a file where the string replacements will be done right in the content.

See, by removing that part, the replacements came out as expected, but if this is for multiple files for the same replacements, then I'd suggest editing the question. Although confusing, for content handling you don't need "Get-ChildItem 'Old and New text.txt' | ...", and you can directly use Get-Content 'Old and New text.txt' ^|...

start "Start PS1/CMD" /wait /min PowerShell.exe -c  ^
"$Strings=Get-Content 'Old And New Text.txt' ^| %%  ^
   ^{ $_ -replace('OldText1','NewText1')^
         -replace('OldText2','NewText2')^
         -replace('OldText3','NewText3')^}^
  ; sc 'Old And New Text.txt' -Value $Strings -Force"
3
  • 1
    Yep, that does work. Thanks for resolving this. The confusing bit: I just left the command how it was, from using "*.txt" in the past. I put the actual name of the file I was trying it on and left Get-ChildItem there because I'm lazy (and stupid when it comes to Powershell haha).
    – bat_cmd
    Commented Feb 11, 2023 at 22:13
  • 2
    At least in (my) W10, you also don't need the foreach: (gc 'file') -replace('a','x') -replace('b','y') ... | sc 'file' (with linebreaks to taste) Commented Feb 12, 2023 at 1:08
  • 1
    @mklement0 I agree with that: "As such, letting -Ex -By stand is a bad example that can confuse others" thanks!
    – Io-oI
    Commented Oct 7, 2023 at 0:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .