Using backslashes to pass a JSON string as a parameter in PowerShell is cumbersome.
executable --json-input '{ \"name\": \"Bob\" }' output.txt
Is there a way to avoid using these backslashes? I tried using single quotes, and doubles quotes in and out without any success. In Python I use triple quotes print(""" here is an example "" """) to avoid character escaping.
Is there a similar solution in PowerShell? One where we never need to worry about reformating a JSON string?
CodePudding user response:
PowerShell has here-strings, similar to the multiline literals from Perl (<<<) or Python (""").
The starting quote must be preceded by @ and immediately followed by a line break, whereas the closing quote must follow a newline and be followed by another @ sign:
command --json-input @"
{ "name": "Bob" }
"@ output.txt
CodePudding user response:
The unfortunate need for manual \-escaping of " chars. embedded in string arguments passed to external programs is due to a long-standing PowerShell bug that may finally get fixed in PowerShell 7.3, though possibly on an opt-in basis - see this answer for details.
- That is to say, you should be able to just pass
'{ "name": "Bob" }'- no\-escaping, but the bug prevents that.
To automate this escaping for now, without having to modify a given JSON string, you can apply a regex-based -replace operation, namely $json -replace '([\\]*)"', '$1$1\"'
# Note: only needed for *external executables*, up to at least PowerShell 7.2.x
executable --json-input ('{ "name": "Bob" }' -replace '([\\]*)"', '$1$1\"') output.txt
Note:
The above replacement operation also handles escaped embedded
"characters correctly.E.g.,
{ "name": "Nat \"King\" Cole" }becomes{ \"name\": \"Nat \\\"King\\\" Cole\" }, with the\before"properly escaped as\\See this regex101.com page for an explanation of the regex and replacement operation (for technical reasons, the linked page uses C#'s string format, which requires escaping
\and"in the regex and substitution expression too, but the solution is equivalent to what is shown here).
If you know your JSON input not to contain them, you can simplify to
-replace '"', '\"'
