How to modify YAML object with given key in object array?

102 views Asked by At

I have the following file contents:

animals:
  - rabbit:
      type: R
  - dog:
      type: D
  - cat:
      type: C

What I would want to do with yq is to find all keys that have an "a" in them ("cat" and "rabbit") and modify the file in place to add a "has_a: true" property, so end up with:

animals:
  - rabbit:
      has_a: true
      type: R
  - dog:
      type: D
  - cat:
      has_a: true
      type: C

Ideally, I'd add the property at the first position, but don't modify any existing keys.

Could someone please give me a pointer how to do this with yq? I tried a whole bunch of things, but can't figure it out.

1

There are 1 answers

0
pmf On BEST ANSWER

This works with both implementations of yq:

.animals[] |= with_entries(select(.key | contains("a")).value.has_a = true)
animals:
  - rabbit:
      type: R
      has_a: true
  - dog:
      type: D
  - cat:
      type: C
      has_a: true

Use the -i option to modify the file in-place. For kislyuk/yq, also add the -y option to produce YAML.


Ideally, I'd add the property at the first position

Properties only have an order in their representation. Logically, they are identical to any other order, and other tools along your processing chain could just revert any effort of ordering them. That said, you could make yq (both implementations in their currrent versions - this might change in the future) to output the new key first by adding the old value to it (in this order):

.animals[] |= with_entries(select(.key | contains("a")).value |= {"has_a": true} + .)
animals:
  - rabbit:
      has_a: true
      type: R
  - dog:
      type: D
  - cat:
      has_a: true
      type: C

Tested with kislyuk/yq 3.2.3, and mikefarah/yq 4.34.2