<p>Hi I would like to update a yaml like string into a yaml</p>
<p>i do have the following yaml file <code>argocd.yaml</code></p>
<pre><code>---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  namespace: mynamespace
  name:my-app
spec:
  project: xxx
  destination:
    server: xxx
    namespace: xxx
  source:
    repoURL: xxx
    targetRevision: dev
    path: yyy
    helm:
      values: |-
        image:
          tag: &quot;mytag&quot;
          repository: &quot;myrepo-image&quot;
          registry: &quot;myregistry&quot;
</code></pre>
<p>and ultimatively I want to replace the value of tag. Unfortunately this is a yaml in a yaml configuration.</p>
<p>My Idea so far was:</p>
<ol>
<li>extract value into another values.yaml</li>
<li>Update the tag</li>
<li>evaluate the values in the argocd.yaml with the values.yaml
So what worked is:</li>
</ol>
<pre><code># get the yaml in the yaml and save as yaml
yq e .spec.source.helm.values argocd.yaml &gt; helm_values.yaml
# replace the tag value
yq e '.image.tag=newtag' helm_values.yaml
</code></pre>
<p>and then I want to add the content of the <code>helm_values.yaml</code> file as string into the <code>argocd.yaml</code>
I tried it the following but I can't get it work</p>
<pre><code># idea 1
###################
yq eval 'select(fileIndex==0).spec.source.helm.values =  select(fileIndex==1) | select(fileIndex==0)' argocd.yaml values.yaml

# this does not update the values but add back slashes 

values: &quot;\nimage:\n  tag: \&quot;mytag\&quot;\n  repository: \&quot;myrepo-image\&quot;\n  registry: \&quot;myregistry\&quot;&quot;

# idea 2
##################
yq eval '.spec.source.helm.values = &quot;'&quot;$(&lt; values.yaml)&quot;'&quot;' argocd.yam

here i am not getting the quite escape correctly and it fails with

Error: Parsing expression: Lexer error: could not match text starting at 2:9 failing at 2:12.
        unmatched text: &quot;newtag&quot;

</code></pre>
<p>Any Idea how to solve this or is there a better way to replace a value in such a file?
I am using yq from <a href="https://mikefarah.gitbook.io/yq" rel="nofollow noreferrer">https://mikefarah.gitbook.io/yq</a></p>

<p>Your second approach can work, but in a roundabout way, as <a href="https://github.com/mikefarah/yq" rel="nofollow noreferrer">mikefarah/yq</a> does not support updating <a href="http://yaml-multiline.info/" rel="nofollow noreferrer">multi-line block literals</a> yet</p>
<p>One way to solve this, with the existing constructs would be to do below, without having to create a temporary YAML file</p>
<pre class="lang-none prettyprint-override"><code>o=&quot;$(yq e '.spec.source.helm.values' yaml | yq e '.image.tag=&quot;footag&quot;' -)&quot; yq e -i '.spec.source.helm.values = strenv(o)' argocd.yaml
</code></pre>
<p>The solution above relies on <a href="https://mikefarah.gitbook.io/yq/operators/env-variable-operators" rel="nofollow noreferrer">passing a user defined variable</a> as a string, that can be used in the yq expression using <code>strenv()</code>. The value for the variable <code>o</code> is set by using <a href="https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html" rel="nofollow noreferrer">Command substitution $(..)</a> feature in bash. Inside the substitution construct, we extract the block literal content as a YAML object and apply another filter to modify the tag as we need. So at the end of substitution, the value of <code>o</code> will be set to</p>
<pre class="lang-yaml prettyprint-override"><code>image:
  tag: &quot;footag&quot;
  repository: &quot;myrepo-image&quot;
  registry: &quot;myregistry&quot;
</code></pre>
<p>The obtained result above is now set to the value of <code>.spec.source.helm.values</code> directly which the inplace modification flag (<code>-i</code>) to apply the changes on the actual file</p>
<hr />
<p>I have raised a feature request in the author's repo to provide a simpler way to do this <a href="https://github.com/mikefarah/yq/issues/974" rel="nofollow noreferrer">Support for updating YAML multi-line strings #974</a></p>
