Update a specific object value under YAML based on a condition using yq

Viewed 951

Using https://github.com/mikefarah/yq v4

Given a sample.yaml file like this:

spec:
  chart:
    name: my-chart
    version: 0.0.1
---
spec:
  chart:
    name: something-else
    version: 0.0.2

I want to update the version value but only for the instance of .spec.chart.version where the sibling .spec.chart.name element == my-chart. The result would need to output the entire yaml file so that I can edit the YAML file inline.

If I use a select like

yq e -i 'select(.spec.chart.name == "my-chart") | .spec.chart.version = "1.0.0"' sample.yaml

The second instance of .spec has been removed:

spec:
  chart:
    name: my-chart
    version: 1.0.0

Any advice?

1 Answers
yq '(.spec.chart | select(.name == "my-chart") | .version) = "1.0"' file.yaml

Explanation:

  • First we want to find all the (potential) nodes we want to update, in this case, it's .spec.chart.
  • Next we filter out those node to be only the ones we're interested in, select(.name == "my-chart")
  • Now we select the field we want to update .version
  • Importantly, the whole LHS is in brackets, so those matching version nodes are passed to the update (=) function. If you don't do this, then the filter happens before (and separately to) the update - and so you only see filtered results.

Disclaimer: I wrote yq

Related