<p>I have a yml file called <code>output.yml</code> which contains a K8s Service, Deployment and Ingress resources like so (lots of fields omitted for brevity):</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
spec:
  selector:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-name
      app.kubernetes.io/instance: instance-name
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-name
        app.kubernetes.io/instance: instance-name
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
</code></pre>
<p>What I would like to do is, for all occurrences of where the key = <code>app.kubernetes.io/instance</code>, replace all values of <code>instance-name</code> with a different value say <code>app-instance-name2</code>. I have tried several things like using the <code>select</code> and <code>has</code> operators like so: <code>yq eval '(.. | select(has(&quot;app.kubernetes.io/instance&quot;))'</code> but it returns all map keys instead of just the one I want to update and then I'm not really sure where to go from there.</p>
<p>At the moment, I am just updating each individual value like so:</p>
<pre><code>yq e '.metadata.labels[&quot;app.kubernetes.io/instance&quot;] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == &quot;Service&quot;).spec.selector[&quot;app.kubernetes.io/instance&quot;] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == &quot;Deployment&quot;).spec.selector.matchLabels[&quot;app.kubernetes.io/instance&quot;] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == &quot;Deployment&quot;).spec.template.metadata.labels[&quot;app.kubernetes.io/instance&quot;] = strenv(INSTANCE_NAME)' -i output.yml
</code></pre>
<p>which works but is pretty verbose so I'd like if there was a succinct single line option?</p>
<p>I am using yq version 4.17.2 from <a href="https://mikefarah.gitbook.io/yq" rel="nofollow noreferrer">https://mikefarah.gitbook.io/yq</a></p>
<p>Any advice is much appreciated</p>

<p>It can be accomplished by doing a <a href="https://mikefarah.gitbook.io/yq/operators/recursive-descent-glob#recursively-find-nodes-with-keys" rel="nofollow noreferrer">recursive decent</a> to identify keys matching your string and update their value part using <code>|=</code></p>
<pre class="lang-none prettyprint-override"><code>yq e '(..|select(has(&quot;app.kubernetes.io/instance&quot;)).[&quot;app.kubernetes.io/instance&quot;]) |= &quot;app-instance-name2&quot;' output.yml
</code></pre>
<p>Starting <a href="https://github.com/mikefarah/yq/releases/tag/v4.18.1" rel="nofollow noreferrer">v4.18.1</a>, the <code>eval</code> flag is the default action, so the <code>e</code> flag can be avoided</p>
