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
。我尝试了几种方法,例如使用 select
和 has
运算符,如下所示: 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.1,eval
标志是默认动作,所以e
标志可以避免
我有一个名为 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
。我尝试了几种方法,例如使用 select
和 has
运算符,如下所示: 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.1,eval
标志是默认动作,所以e
标志可以避免