2

I'm working with json in bash, but I'm getting this parse error:

parse error: Invalid numeric literal at line 1, column 2

What's wrong with this block of code?

jsonStr=$(cat << EOF
'{"key1": "value1", "key2": "value2", "key3": "value3"}'
EOF
)
jsonStr=$(jq 'del(.key3)' <<<"$jsonStr")
STRING="hello"
jsonStr=$(jq '. + {'"$STRING"': "value4"}' <<<"$jsonStr")
echo $jsonStr
peak
  • 105,803
  • 17
  • 152
  • 177
mehtaarn000
  • 176
  • 1
  • 3
  • 11
  • 1
    In addition to the literal quotes making your data no longer JSON (which is the main issue, and covered in markp-fuso's answer), note that `echo $jsonStr` is inherently buggy. See [BashPitfalls #14](https://mywiki.wooledge.org/BashPitfalls#echo_.24foo) and [I just assigned a variable, but `echo $variable` prints something else!](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) -- as in markp's answers, you need double quotes around your parameter expansions, even if their results are passed to `echo`, to prevent potential surprises – Charles Duffy Nov 22 '20 at 23:46
  • The correct input still contains no numeric literal. The error message is misleading —and doesn't say it comes from jq... – Ale Sep 18 '22 at 10:43

1 Answers1

9

The $(cat << EOF ...) construct is passing the single quotes along as part of the data, ie:

$ jsonStr=$(cat << EOF
'{"key1": "value1", "key2": "value2", "key3": "value3"}' 
EOF
)
$ echo "${jsonStr}"
'{"key1": "value1", "key2": "value2", "key3": "value3"}'

Notice the leading/trailing single quotes.

To get past the parsing error you want to get rid of the single quotes, eg:

$ jsonStr=$(cat << EOF
{"key1": "value1", "key2": "value2", "key3": "value3"}
EOF
)

# or

$ jsonStr='{"key1": "value1", "key2": "value2", "key3": "value3"}'

Both of the above give us:

$ echo "${jsonStr}"
{"key1": "value1", "key2": "value2", "key3": "value3"}

And now the jq/del works as expected:

$ jq 'del(.key3)' <<< "${jsonStr}"
{
  "key1": "value1",
  "key2": "value2"
}

And then the + operation also works:

$ STRING="hello"
$ jq 'del(.key3)' <<< "${jsonStr}"  | jq '. + {'"$STRING"': "value4"}'
{
  "key1": "value1",
  "key2": "value2",
  "hello": "value4"
}

Pulling this all together:

jsonStr='{"key1": "value1", "key2": "value2", "key3": "value3"}'
jsonStr=$(jq 'del(.key3)' <<< "${jsonStr}")
STRING="hello"
jsonStr=$(jq '. + {'"${STRING}"': "value4"}' <<< "${jsonStr}")
echo "${jsonStr}"

Which generates:

{
  "key1": "value1",
  "key2": "value2",
  "hello": "value4"
}
markp-fuso
  • 28,790
  • 4
  • 16
  • 36