1

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
  • 21,637
  • 21
  • 47
  • 71
WeSee
  • 182
  • 1
  • 1
  • 12
  • 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](https://unix.stackexchange.com/questions/118433/quoting-within-command-substitution-in-bash) 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
  • 320,670
  • 36
  • 633
  • 936
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,472
  • 1
  • 35
  • 52
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
  • 28,789
  • 5
  • 20
  • 47