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 '"', '\"'