2

My awk outputs a multiline string.

awkresult=`awk '{...}'`
echo "{ \"result\": \"$awkresult\" }" > result.json

The multilines must be preserved in the result string.

I think the best way is to insert newlines at the end of each line in awkresult.

My awk script cannot be modified. How should I modify my code?

AdminBee
  • 22,803
WeSee
  • 202
  • 1
    What do you mean specifically by you cannot modify your script? Additionally, could you please update your post to include the exact format you are expecting? Thank you. – kemotep May 02 '20 at 10:27
  • Please [edit] your question to show a sample of awkresult that includes newlines and the output you want to see in result.json given that input. Right now we're all making different guesses about whether you mean a literal linefeed character or the 2-character string \n in your input and your output. – Ed Morton May 02 '20 at 23:45
  • 1
    Please note that the "backtick"-style for command substitutions is deprecated, and the $( ... ) notation is the recommended standard. Also, quoting is an important subject when it comes to shell variables. – AdminBee May 05 '20 at 14:33
  • The multi line result is an error: awk: cmd. line:1: {...} awk: cmd. line:1: ^ syntax error – Volker Siegel May 11 '20 at 11:26

4 Answers4

6

Note that newlines in values must be encoded as \n in JSON. A JSON parser would decode these as real newlines. Insertin a literal newline in a value in a JSON file would result in a broken JSON document.

Using jo (a tool for generating JSON output in the shell, with the correct encoding etc.):

awkresult='some string
with newlines
the end'

jo result="$awkresult"

This would result in the output

{"result":"some string\nwith newlines\nthe end"}

To pretty print:

jo -p result="$awkresult"

which results in

{
   "result": "some string\nwith newlines\nthe end"
}

Redirect the output of jo to a file to save the output, e.g.

jo result="$awkresult" >result.json
Kusalananda
  • 333,661
2

You can use HERE document like below :

echo "$(cat <<EOM
{ "result" : "$awkresult" }
EOM
)" > result.json

Note the double-quotes " in echo statement , it preservers all newlines and you dont have to escape \" quotes inside.

1

Your idea was right, but don't use double-quotes to encode the JSON string. Use single quotes around the {..}, use a special quoting sequence to expand the awkresult inside the single quotes

awkresult='foo\nbar\nzoo\n'

now, use the variable as

echo '{ "result": "'"$awkresult"'" }' > result.json

Also remember that the JSON specification does "not" allow literal newline control characters to be embedded. You can verify if the JSON snippet is valid

echo '{ "result": "'"$awkresult"'" }' | jq .
{
  "result": "foo\nboo\nbar\n"
}
Inian
  • 12,807
1

The code you posted already will preserve newlines in $awkresult:

$ awkresult='foo
bar'
$ echo "{ \"result\": \"$awkresult\" }"
{ "result": "foo
bar" }

but here's a simpler, more robust, more portable, way to do the same:

awkresult="$(awk '{...}')"
printf '{ "result": "%s" }\n' "$awkresult" > result.jso

Or did you mean you have to replace newlines with \n strings like this

$ printf '{ "result": "%q" }\n' "$awkresult"
{ "result": "$'foo\nbar'" }

or something else?

Ed Morton
  • 31,617