1

I'm trying to iterate through an object and convert any value (top level only for now, no recursion) that is a valid json string to json.

I think the answer lies in using the correct incantation perhaps something like with_entries(.value |= try fromjson), but I'm having trouble getting it working. So I broke it down a bit to try something simpler.

How about the following list of objects - I just want to parse the value key of each of them if it is a string that yields valid json (let's ignore the invalid cases for now, they can return null).

So I tried this:

$ jq -n '[{key: "one", value: 1},{key: "two", value: "{\"object\":true}"}] | map(.value |= try fromjson)'
[
  {
    "key": "one"
  },
  {
    "key": "two"
  }
]

Values are both missing even though the two key is a valid json string.

But if I try the same with a simple array, it works as expected:

$ jq -n '[1, "two", "{\"three\":3}"] | .[] | fromjson?'
{
  "three": 3
}

So my question is what I am doing wrong here? Thanks in advance for any pointers.

ec2011
  • 570
  • 6
  • 20
  • I have found what may be a related question, but I prefer Peak's answer given below. https://stackoverflow.com/questions/66101660/use-jq-to-interpret-nested-json-in-json – ec2011 Mar 19 '21 at 11:12

1 Answers1

2

You have come across one of the (somewhat well-known) deficiencies of jq, namely that the trio of map, |=, try (and therefore postfix ?) do not mix well.

The good news is that the following will work in jq 1.5 and later:

map(.value = (.value | . as $v | try fromjson catch $v))

or equivalently:

map(.value as $v | .value = try ($v|fromjson) catch $v)
peak
  • 105,803
  • 17
  • 152
  • 177