1

I want to use the following command

powershell -command "get-content %CONFIG_FILE% | %{$_ -replace \"APP_PATH=.+\",\"APP_PATH=%APP_DIR%\"}"

but with the evaluation of the %CONFIG_FILE% and the %APP_DIR% which are defined in the batch script using

set CONFIG_FILE=C:\B0_GW.cfg 
set APP_DIR=C:\dbg\kernel

when i do so, i currently get the following issue:

The string is missing the terminator: ".

+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException

+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

any ideas?

Community
  • 1
  • 1
Mo SAEED
  • 43
  • 1
  • 8
  • 2
    I guess you need to escape the `%`-symbol in `%{$_` by doubling it: `%%{$_`... – aschipfl Feb 26 '19 at 20:22
  • 2
    In the Batch file, below the two `set` commands, put: `powershell get-content %CONFIG_FILE% ^| %%{$_ -replace \"APP_PATH=.+\",\"APP_PATH=%APP_DIR%\"}` or just `powershell get-content %CONFIG_FILE% ^| %%{$_ -replace "APP_PATH=.+","APP_PATH=%APP_DIR%"}` – Aacini Feb 26 '19 at 20:30
  • @Aacini: It's better to keep the enclosing `"..."` around the PowerShell code, because without them an `%APP_PATH%` value with two or more adjacent embedded spaces (however rare that may be) will break the command. Your 2nd suggestion always breaks, because PowerShell strips unescaped `"` during CLI parsing _before_ interpreting the code. – mklement0 Feb 27 '19 at 18:36

1 Answers1

2

aschipfl has provided the crucial pointer in a comment on the question:

From within a batch file[1], you must escape % characters that you want to pass through to the target application as %%.

Otherwise, cmd interprets % as the start or end of an environment-variable reference (which in part happens by design in your command; e.g., %CONFIG_FILE%).

(You've already correctly escaped embedded " chars. in your command as \" for PowerShell).

Specifically, the % in the %{...} part of your command needs escaping (% is PowerShell's built-in alias for the ForEach-Object cmdlet):

powershell -command "get-content %CONFIG_FILE% | %% {$_ -replace \"APP_PATH=.+\",\"APP_PATH=%APP_DIR%\"}"

Alternatively, simply use the cmdlet's actual name, ForEach-Object, which obviates the need for escaping:

powershell -command "get-content %CONFIG_FILE% | ForEach-Object {$_ -replace \"APP_PATH=.+\",\"APP_PATH=%APP_DIR%\"}"

[1] Sadly, the behavior at cmd.exe's command prompt (in an interactive session) differs - see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775