I wish I could use yq to iterate a yaml recursively, find all key-value pairs, whose key is image
and value type is string
(!!str), then add a prefix to the original value.
Input:
serving:
template:
image: "docker.io/serving"
custom:
template:
image:
type: string
description: "..."
eventing:
image: "docker.io/eventing"
Add a prefix private.io/
to all image
field if its value type is string
(!!str) recursively.
Expected output:
serving:
template:
image: "private.io/docker.io/serving"
custom:
template:
image:
type: string
description: "..."
eventing:
image: "private.io/docker.io/eventing"
For a equivalent json, I can use the walk
operator to do such thing:
jq 'walk(if type == "object" and has("image") and (.image|type) == "string" then .image = "private.io/" + .image else . end)' input.json
Is there any equivalent operator like walk
, I have tried the ..
operator
yq '.. | select(tag == "!!str" and key == "image") |= "private.io/" + . ' input.json
But this command add some entries to the yaml, result in:
serving:
template:
image: "private.io/docker.io/serving"
custom:
template:
image:
type: string
description: "..."
eventing:
image: "private.io/docker.io/eventing"
template:
image: "private.io/docker.io/serving"
image: "private.io/docker.io/serving"
private.io/docker.io/serving
template:
image:
type: string
description: "..."
image:
type: string
description: "..."
type: string
description: "..."
string
...
image: "private.io/docker.io/eventing"
private.io/docker.io/eventing
Any ideas or walk around ? Thanks, sincerely~
There is, and you almost had it. Just set parentheses to retain the context:
yq '(.. | select(key == "image" and type == "!!str")) |= "private.io/" + .'
serving:
template:
image: "private.io/docker.io/serving"
custom:
template:
image:
type: string
description: "..."
eventing:
image: "private.io/docker.io/eventing"
Tested with mikefarah/yq v4.31.1
Note: With kislyuk/yq or itchyny/gojq you can also use your original walk
filter on your YAML input. Both tools can process YAML files using proper jq syntax.
yq -y 'walk(
if type == "object" and has("image") and (.image|type) == "string"
then .image |= "private.io/" + . else . end
)'
# or
gojq --yaml-input --yaml-output 'walk(
if type == "object" and has("image") and (.image|type) == "string"
then .image |= "private.io/" + . else . end
)'