Home > Net >  Pass a JSON string without using backslashes
Pass a JSON string without using backslashes

Time:07-22

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

  • Related