yq修改YAML:如何保留双引号内的单引号?
解决yq修改YAML时保留双引号内单引号的问题
问题场景
在Ubuntu机器上使用yq 4.27.3修改YAML文件,目标是为指定条目更新with_items字段的值,需要保留字段值双引号内的单引号,但执行命令后单引号丢失。
现有YAML内容(example.yaml)
- name: Kubernetes Apps | Install ArgoCD become: yes kube: name: ArgoCD kubectl: "{{ bin_dir }}/kubectl" filename: "{{ kube_config_dir }}/{{ item.file }}" state: latest with_items: "{{ argocd_templates }}" when: - "inventory_hostname == groups['kube_control_plane'][0]"
原执行命令及问题
执行的yq命令:
yq -i '(.[] | select(.name == "Kubernetes Apps | Install ArgoCD") | .with_items) = "{{ argocd_templates | rejectattr('name', 'eq', 'bootstrap') | list }}"' example.yaml
执行后输出(丢失单引号):
with_items: "{{ argocd_templates | rejectattr(name, eq, bootstrap) | list }}"
期望输出(保留单引号):
with_items: "{{ argocd_templates | rejectattr('name', 'eq', 'bootstrap') | list }}"
解决方案
问题出在shell对引号的解析上,需要正确转义表达式内的单引号,以下两种方式均可:
方式1:单引号包裹yq表达式,内部单引号用'\''转义
yq -i '(.[] | select(.name == "Kubernetes Apps | Install ArgoCD") | .with_items) = "{{ argocd_templates | rejectattr('\''name'\'', '\''eq'\'', '\''bootstrap'\'') | list }}"' example.yaml
解释:shell中,'\''的写法可以在单引号包裹的字符串中插入单引号——先关闭当前单引号,输出一个转义的单引号,再重新开启单引号。
方式2:双引号包裹yq表达式,内部双引号用反斜杠转义
yq -i "(.[] | select(.name == \"Kubernetes Apps | Install ArgoCD\") | .with_items) = \"{{ argocd_templates | rejectattr('name', 'eq', 'bootstrap') | list }}\"" example.yaml
解释:用双引号包裹整个yq表达式时,内部的双引号需要用\转义,而单引号可以直接使用,无需额外转义。
执行任意一种命令后,即可得到期望的YAML内容。
内容的提问来源于stack exchange,提问作者warmichi
相关产品推荐
相关产品推荐

