使用 jq 更新对象中其他字段标识的数组元素
Updating an array element identified by other fields in the object using jq
目标
我想在我的 kubeconfig 文件的当前活动 clusters
条目中添加一个 proxy-url
字段。 “活动”集群由“活动”上下文标识,“活动”上下文本身由顶级键 current-context
标识。简化后,JSON 对象类似于:
{
"clusters":[
{
"name":"cluster1",
"field":"field1"
},
{
"name":"cluster2",
"field":"field2"
}
],
"contexts":[
{
"name":"context1",
"context": {
"cluster":"cluster1"
}
},
{
"name":"context2",
"context": {
"cluster":"cluster2"
}
}
],
"current-context": "context1"
}
我想更新 cluster1
的 clusters
条目来自:
{
"name":"cluster1",
"field":"field1"
}
到
{
"name":"cluster1",
"field":"field1",
"proxy-url":"my-url"
}
第一次尝试
jq '. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name) as $context
| $o.clusters[] | select(.name == $context.context.cluster)
| .proxy_id |= "my-url"'
给我
{
"name": "cluster1",
"field": "field1",
"proxy_id": "my-url"
}
-- 太棒了!但我也需要对象的其余部分。
括号几乎可以工作
使用括号,我可以取回整个对象并向活动 context 添加一个“proxy-url”字段,但我不能接受进一步更新活动 集群 。此过滤器:
jq '(. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name)
| ."proxy-url")
|= "my-url"'
作品薄荷:
{
"clusters": [...], // omitted for brevity, unchanged
"contexts": [
{
"name": "context1",
"context": {
"cluster": "cluster1"
},
"proxy-url": "my-url" // tada!
},
{...} // omitted for brevity, unchanged
],
"current-context": "context1"
}
尝试更进一步(改为更新由 context
标识的 cluster
):
jq '(. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name) as $context
| $o.clusters[] | select(.name == $context.context.cluster)
| ."proxy-url")
|= "my-url"'
给我以下错误:
jq: error (at <stdin>:26): Invalid path expression near attempt to access element "clusters" of {"clusters":[{"name":"clus...
exit status 5
如何使用 $context.context.cluster
结果更新相关的 clusters
条目?我不明白为什么这种方法适用于向 contexts
添加内容但不适用于 clusters
.
肮脏的解决方案
我可以拼凑一个新的 clusters
条目并将其与顶级对象合并:
jq '. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name) as $context
| $o + {"clusters": [($o.clusters[] | select(.name == $context.context.cluster)."proxy-url" |= "my-url")]}
但这感觉有点脆弱。
此解决方案使用 INDEX
构造检索活动集群,然后直接设置新字段而不修改上下文:
jq '
INDEX(.contexts[]; .name)[."current-context"].context.cluster as $cluster
| (.clusters[] | select(.name == $cluster))."proxy-url" = "my-url"
'
{
"clusters": [
{
"name": "cluster1",
"field": "field1",
"proxy-url": "my-url"
},
{
"name": "cluster2",
"field": "field2"
}
],
"contexts": [
{
"name": "context1",
"context": {
"cluster": "cluster1"
}
},
{
"name": "context2",
"context": {
"cluster": "cluster2"
}
}
],
"current-context": "context1"
}
目标
我想在我的 kubeconfig 文件的当前活动 clusters
条目中添加一个 proxy-url
字段。 “活动”集群由“活动”上下文标识,“活动”上下文本身由顶级键 current-context
标识。简化后,JSON 对象类似于:
{
"clusters":[
{
"name":"cluster1",
"field":"field1"
},
{
"name":"cluster2",
"field":"field2"
}
],
"contexts":[
{
"name":"context1",
"context": {
"cluster":"cluster1"
}
},
{
"name":"context2",
"context": {
"cluster":"cluster2"
}
}
],
"current-context": "context1"
}
我想更新 cluster1
的 clusters
条目来自:
{
"name":"cluster1",
"field":"field1"
}
到
{
"name":"cluster1",
"field":"field1",
"proxy-url":"my-url"
}
第一次尝试
jq '. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name) as $context
| $o.clusters[] | select(.name == $context.context.cluster)
| .proxy_id |= "my-url"'
给我
{
"name": "cluster1",
"field": "field1",
"proxy_id": "my-url"
}
-- 太棒了!但我也需要对象的其余部分。
括号几乎可以工作
使用括号,我可以取回整个对象并向活动 context 添加一个“proxy-url”字段,但我不能接受进一步更新活动 集群 。此过滤器:
jq '(. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name)
| ."proxy-url")
|= "my-url"'
作品薄荷:
{
"clusters": [...], // omitted for brevity, unchanged
"contexts": [
{
"name": "context1",
"context": {
"cluster": "cluster1"
},
"proxy-url": "my-url" // tada!
},
{...} // omitted for brevity, unchanged
],
"current-context": "context1"
}
尝试更进一步(改为更新由 context
标识的 cluster
):
jq '(. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name) as $context
| $o.clusters[] | select(.name == $context.context.cluster)
| ."proxy-url")
|= "my-url"'
给我以下错误:
jq: error (at <stdin>:26): Invalid path expression near attempt to access element "clusters" of {"clusters":[{"name":"clus...
exit status 5
如何使用 $context.context.cluster
结果更新相关的 clusters
条目?我不明白为什么这种方法适用于向 contexts
添加内容但不适用于 clusters
.
肮脏的解决方案
我可以拼凑一个新的 clusters
条目并将其与顶级对象合并:
jq '. as $o
| $o."current-context" as $current_context_name
| $o.contexts[] | select(.name == $current_context_name) as $context
| $o + {"clusters": [($o.clusters[] | select(.name == $context.context.cluster)."proxy-url" |= "my-url")]}
但这感觉有点脆弱。
此解决方案使用 INDEX
构造检索活动集群,然后直接设置新字段而不修改上下文:
jq '
INDEX(.contexts[]; .name)[."current-context"].context.cluster as $cluster
| (.clusters[] | select(.name == $cluster))."proxy-url" = "my-url"
'
{
"clusters": [
{
"name": "cluster1",
"field": "field1",
"proxy-url": "my-url"
},
{
"name": "cluster2",
"field": "field2"
}
],
"contexts": [
{
"name": "context1",
"context": {
"cluster": "cluster1"
}
},
{
"name": "context2",
"context": {
"cluster": "cluster2"
}
}
],
"current-context": "context1"
}