6

So I can do this

jq --arg title "Test" 'select(.title == $title) | .alert.notifications = [{"uid":"foo"},{"uid":"bar"}]' json

Which outputs the desired results:

{
  "alert": {
    "notifications": [
      { 
        "uid": "foo" 
      },
      { 
        "uid": "bar" 
      }
    ]
  },
  "title": "Test"
}

However, I need to put the array in a var and supply it on the fly instead, like:

array='{ "uid": "foo" },{ "uid": "bar"}'

jq -r --arg title "$t" --arg array "$array" 'select(.title == $title) | .alert.notifications = [$array]'

But that results in this undesired output

{
  "alert": {
    "notifications": [
      "{ \"uid\": \"foo\" },{ \"uid\": \"bar\" }"
    ]
  },
  "title": "Test"
}

Any way to get around this? Much appreciated!!

1 Answer 1

6

Use --argjson (instead of --arg) for JSON input. Note, however, that {"uid": "foo" }, {"uid": "bar"} by itself is not (yet) valid JSON. You need to wrap it into brackets to make it an array (otherwise, jq will (rightfully) complain about a superfluous comma between the two objects).

Brackets added to the string provided for --argjson:

array='{"uid": "foo" }, {"uid": "bar"}'

jq --arg title "$t" --argjson array "[$array]" \
  'select(.title == $title) | .alert.notifications = $array'

Brackets added to the shell variable called array:

array='[{"uid": "foo" }, {"uid": "bar"}]'

jq --arg title "$t" --argjson array "$array" \
  'select(.title == $title) | .alert.notifications = $array'

Also note that if your output is JSON, you don't need the -r option.

{
  "alert": {
    "notifications": [
      {
        "uid": "foo"
      },
      {
        "uid": "bar"
      }
    ]
  },
  "title": "Test"
}

If you don't have the option to use --argjson instead of --arg (because, for example, the input may or may not be JSON and you can only test it after populating the variables), you can use the fromjson builtin to convert a JSON-encoded string into actual JSON (said "testing" is not included in these examples).

Brackets added inline just before applying fromjson:

array='{"uid": "foo" }, {"uid": "bar"}'

jq --arg title "$t" --arg array "$array" \
  'select(.title == $title) | .alert.notifications = ("[\($array)]" | fromjson)'

Brackets added to the string provided for --arg:

array='{"uid": "foo" }, {"uid": "bar"}'

jq --arg title "$t" --arg array "[$array]" \
  'select(.title == $title) | .alert.notifications = ($array | fromjson)'

Brackets added to the shell variable called array:

array='[{"uid": "foo" }, {"uid": "bar"}]'

jq --arg title "$t" --arg array "$array" \
  'select(.title == $title) | .alert.notifications = ($array | fromjson)'
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.