yq - 通过映射键查找和替换映射值

yq - Find and replace map value by map key

我有一个名为 output.yml 的 yml 文件,其中包含 K8s 服务、部署和 Ingress 资源,如下所示(为简洁起见省略了很多字段):

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

我想做的是,对于所有出现的 key = app.kubernetes.io/instance,将 instance-name 的所有值替换为不同的值,比如 app-instance-name2。我尝试了几种方法,例如使用 selecthas 运算符,如下所示: yq eval '(.. | select(has("app.kubernetes.io/instance"))' 但它 returns 所有映射键,而不仅仅是我要更新的键,然后我我不太确定从那里去哪里。

目前,我只是像这样更新每个单独的值:

yq e '.metadata.labels["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == "Service").spec.selector["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == "Deployment").spec.selector.matchLabels["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == "Deployment").spec.template.metadata.labels["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml

这行得通,但非常冗长,所以我想知道是否有简洁的单行选项?

我正在使用 https://mikefarah.gitbook.io/yq

的 yq 版本 4.17.2

非常感谢任何建议

可以通过 recursive decent 识别与您的字符串匹配的键并使用 |=

更新它们的值部分来完成
yq e '(..|select(has("app.kubernetes.io/instance")).["app.kubernetes.io/instance"]) |= "app-instance-name2"' output.yml

开始v4.18.1eval标志是默认动作,所以e标志可以避免