1

cat file.json gives me what I want to capture inside of $JSON:

{ 
  key: "value\nwith\nnewline\nchars"
}

I can't do JSON=$(cat file.json) though because then the newline characters are translated and I get after echo $JSON or echo -e $JSON.

{
 key: "value
with
newline
chars"
}.

How can I preserve the newline characters inside of $JSON?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Dane Jordan
  • 1,071
  • 1
  • 17
  • 27
  • 1
    No, they aren't translated on capture/assignment. How are you *displaying* the value of the variable? More likely it's translating them on display, and the capture is actually fine. – Charles Duffy Feb 10 '19 at 03:00
  • 1
    Try `printf '%s\n' "$JSON"` to display the `JSON` variable's value accurately. (**Do not** use `printf "$JSON\n"`, and `echo` may or may not be reliable depending on runtime configuration). – Charles Duffy Feb 10 '19 at 03:01
  • 1
    Right -- don't use `echo -e`; that *explicitly tells* `echo` (when in bash's default standard-noncompliant mode) to replace `\n` with a literal newline. – Charles Duffy Feb 10 '19 at 03:02
  • 1
    See the answer at https://stackoverflow.com/a/52451742/14122 – Charles Duffy Feb 10 '19 at 03:03
  • Thanks @CharlesDuffy! Go ahead and give an answer and the glorious 10 points will await you – Dane Jordan Feb 10 '19 at 03:04
  • I was literally staring at the answer when I gave up :| https://linuxconfig.org/bash-printf-syntax-basics-with-examples. I think my brain is full for the day. – Dane Jordan Feb 10 '19 at 03:05
  • 1
    BTW, the APPLICATION USAGE section of [the POSIX spec for `echo`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html) is relevant. – Charles Duffy Feb 10 '19 at 03:07

1 Answers1

3

Capture using command substitution doesn't perform the translation you're worried about here, but using echo (or misusing printf by substituting into the format string rather than a separate parameter) will.


To emit a variable with backslash sequences intact, use:

printf '%s\n' "$JSON"

This avoids behavior that echo can have (either explicitly with bash's noncompliant extension for echo -e, or implicitly when the xpg_echo flag is enabled in bash, or as default out-of-the-box behavior with other, POSIX+XSI-compatible /bin/sh implementations) wherein escape sequences are replaced by echo, even if the variable passed as an argument had a multi-character backslash sequence.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441