I have a file that contains new line characters.
I am posting the file via curl to a server that would parse it as json.
It rejects the request due to the new line characters.
But when I do:

$(echo "$MY_DATA" | sed 's/$//' | tr -d '\n\r')  

It works but the new line characters are gone.
How can I escape the text so that it keeps the new line characters?
I tried tr '\n' '\\n' and sed 's/\n/\\n/g and neither approach worked

  • to a server that would parse it as json - what's your $MY_DATA value and expected result – RomanPerekhrest Jul 6 '18 at 15:06
  • @RomanPerekhrest: It is just a 2 line string (all ascii) with a new line char between. The only change I do for it to work is remove the new line. – Jim Jul 6 '18 at 15:11
  • you wrote for json, if it's JSON string - post its value – RomanPerekhrest Jul 6 '18 at 15:23

I assume you want to change raw newline characters to \n (a backslash and an n).

tr '\n' '\\n' would change newlines to backslashes (and then there's an extra n in the second set). sed 's/\n/\\n/g won't work because sed doesn't load the line-terminating newline into the buffer, but handles it internally.

Some alternatives are GNU sed with -z (takes the input as NUL-separated "lines", not newline-separated):

sed -z 's/\n/\\n/g'

and Perl (unlike sed, it does take the newline in the buffer, so s/// works on it):

perl -pe 's/\n/\\n/g'

(tr -d '\n\r' will indeed remove newlines, that's exactly what you're asking it to do.)

  • You may want to format the json as one line, as this could mess up the formatting and make it invalid. – ctrl-alt-delor Jul 6 '18 at 17:11
  • Works perfectly! Thank you. I didn't get the part about: ` then there's an extra n in the second set. So tr '\n' '\\n'` would replace \n with \`? and then append an n? So the result would be \\n` but it wouldn't be considered new line char? – Jim Jul 6 '18 at 19:10
  • @ctrl-alt-delor: What do you mean? – Jim Jul 6 '18 at 19:15
  • 1
    @Jim, no, the a is translated to a literal backslash, then b to n and c is left unchanged. When tr gets the string \\n, it takes the two backslashes to mean a single backslash, in the same way it would take \n to mean a newline. | tr 'ab' '\\x' would be similar, you'd just get b changed to an x. There's no translation to newlines here. (yeah the comment formatting doesn't really like backslashes and backticks) – ilkkachu Jul 9 '18 at 10:23
  • 1
    @ilkkachu:Ah I see now. I see that "echo "abc" |tr 'ab' 'z\n'" actually converts to new line char – Jim Jul 9 '18 at 10:46

Use jq to properly JSON encode the data:

printf '%s' "$MY_DATA" | jq -sR .

The -s (--slurp) and -R (--raw-input) options, when used together, will read the raw input data and create a single JSON-encoded string out of it.


MY_DATA='line 1
line 2 contains a literal tab   <-- there
line 3 "the end"'

printf '%s' "$MY_DATA" | jq -sR .


"line 1\nline 2 contains a literal tab\t<-- there\nline 3 \"the end\""

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.