-1

My Bash script has lots of variable assignments which are put in a JSON file:

var='Hello
    "world". 
    This is \anything \or \nothing
'
echo "{ \"var\"= \"$var\" }" > output.json

When validating the file output.json jq says:

$ cat output.json | jq .
parse error: Invalid numeric literal at line 1, column 9

How can I make a valid JSON file out of it? Any \ and " should be preserved.

The correct JSON string would be

{ "var": "Hello
    \"world\". 
    This is \\anything \\or \\nothing
  " }

I cannot modify the variable assignments but the JSON creation.

oguz ismail
  • 1
  • 16
  • 47
  • 69
WeSee
  • 3,158
  • 2
  • 30
  • 58
  • 1
    JSON strings can not contain line feeds, your expected output is not a valid JSON value. – oguz ismail May 02 '20 at 18:33
  • `echo "{\"x\":\"a\n\"}" | jq .` is valid with a newline! – WeSee May 02 '20 at 18:35
  • 2
    \n is an escape sequence representing line feed character, it's not a literal line feed. Your expected output contains literal line feed characters – oguz ismail May 02 '20 at 18:38
  • you can use `sed` if jq is not available https://stackoverflow.com/questions/1251999/how-can-i-replace-each-newline-n-with-a-space-using-sed – Summer-Sky Jun 29 '23 at 07:58

2 Answers2

2

Pass $var as a raw string argument and JQ will automatically convert it to a valid JSON string.

$ jq -n --arg var "$var" '{$var}'
{
  "var": "Hello\n    \"world\". \n    This is \\anything \\or \\nothing\n"
}
oguz ismail
  • 1
  • 16
  • 47
  • 69
-1

"JSON strings can not contain line feeds", as oguz ismail already mentioned, so it's better to let dedicated tools like xidel (or jq) convert the line feeds to a proper escape sequence and to valid JSON.

Stdin:

$ var='Hello
    "world". 
    This is \anything \or \nothing
'

$ xidel - -se '{"var":$raw}' <<< "$var"
{
  "var": "Hello\n    \"world\". \n    This is \\anything \\or \\nothing\n"
}

Environment variable:

$ export var='Hello
    "world".
    This is \anything \or \nothing
'

$ xidel -se '{"var":environment-variable("var")}'
{
  "var": "Hello\n    \"world\". \n    This is \\anything \\or \\nothing\n"
}
Reino
  • 3,203
  • 1
  • 13
  • 21