Home > Software design >  Update JSON string field in yaml using yq
Update JSON string field in yaml using yq

Time:11-19

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"
    }
---

CodePudding user response:

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

CodePudding user response:

Basically, remove tostring

json=$(
    yq 'select(.action == "want-to-update").foo' sample.yaml \
    | jq '.a = "updated a"'
)
escaped_quotes=${json//\"/\\\"}
yq 'select(.action == "want-to-update").foo = "'"${escaped_quotes}"'"' sample.yaml
---
action: "want-to-update"
foo: |-
  {
    "a": "updated a",
    "b": "actual B",
    "c": "actual C"
  }

---
action: "dont-want-to-update"
foo: |-
  "ok"

  • Related