Add JSON value in correct section

2019-07-20 15:29发布

My json file 'veggies.json' as follows:

{"plants":
  {"veggies":
    [
      {"section":"TUBERS",
        "values":
          [
            {"tuber":"potato","type":"stem"}
          ]
      },
      {"section":"LEGUMES",
        "values":
          [
            {"legume":"beans"},
            {"legume":"peanuts"}
          ]
      }
    ]
  }
}

I want to add another tuber "yam", which is of type "root" - this has to go under the section TUBERS.

I've just started off with JSON, and I have been breaking my head with all sorts of jq commands, but to not much avail.

I tried to read the value at values[0] with the following command, but I don't seem to be able to list anything:

jq -r "[.[] | select(.plants.veggies.section == \"TUBERS\") | .plants.veggies.values.tuber]" veggies.json

Essentially, I am trying to achieve this - if plants section is TUBERS, add tuber "yam" which is of type "root"

Can anybody please help me out?

Oh, and I am stuck with jq version 1.2, if that matters (backward compatibility and all that stuff).

Much thanks in advance.

标签: json shell jq
2条回答
Root(大扎)
2楼-- · 2019-07-20 16:16

Never mind - after some more head-cracking, I think I got it:

cat veggies.json | jq '.plants.veggies[] | select(.section == "TUBERS") | .values |= . + [{ "type": "root", "tuber": "yam" }]'

This seems to do what I want:

{
  "values": [
    {
      "type": "stem",
      "tuber": "potato"
    },
    {
      "tuber": "yam",
      "type": "root"
    }
  ],
  "section": "TUBERS"
}

If somebody can optimize this even further, I'd be very eager to learn that as well.

查看更多
beautiful°
3楼-- · 2019-07-20 16:19

Try this instead:

jq '(.plants.veggies[] | select(.section == "TUBERS") | .values) |= . + [{"type": "root", "tuber": "yam"}]' veggies.json

This runs a sub-filter: selecting the elements of the veggies array, finding the element with a matching section and yielding the values varray. Then it appends the object to the values array.

This is essentially the same as the filters in your own answer with one key difference: because you don't actually filter anything out of the main input data, it will print out the entire JSON document (not just the modified portion). I'm not sure if that's a benefit to you or not, but it makes it really easy to modify the document as a whole in a script.

(tested on jq 1.3)

查看更多
登录 后发表回答