Search code examples
shelljqyq

Update JSON string field in yaml using yq


Have a file sample.yaml

---
action: "want-to-update"
foo: |-
    {
        "a" : "actual A",
        "b" : "actual B",
        "c" : "actual C"
    }
---
action: "dont-want-to-update"
foo: |-
.
.
.

Need to update value in a field from actual a to updated a

Tried to update with yq and jq

yq 'select(.action == "want-to-update").foo' sample.yaml | jq '.a = "updated a" | tostring' | xargs -0 -n1 -I{} yq 'select(.action == "want-to-update").foo = {}' -i sample.yaml

Getting output as below:

---
action: "want-to-update"
foo: |-
  {"a":"updated a","b":"actual B","c":"actual C"}
---
.
.

But I want the prettier version of above:

---
action: "want-to-update"
foo: |-
    {
        "a" : "updated A",
        "b" : "actual B",
        "c" : "actual C"
    }
---

Solution

  • Using fromjson and tojson, you can decode and encode JSON on the fly, so all of this can be done with just one call to yq (no jq and no command substitution needed):

    yq -i 'select(.action == "want-to-update").foo |= (
      fromjson | .a = "updated a" | tojson
    )' sample.yaml