修改 JSON jq 中的键值数组
Modifying array of key value in JSON jq
以防万一,我有一个原始的 json 如下所示:
{
"taskDefinition": {
"containerDefinitions": [
{
"name": "web",
"image": "my-image",
"environment": [
{
"name": "DB_HOST",
"value": "localhost"
},
{
"name": "DB_USERNAME",
"value": "user"
}
]
}
]
}
}
我想就地修改匹配键的值,如下所示:
jq '.taskDefinition.containerDefinitions[0].environment[] | select(.name=="DB_USERNAME") | .value="new"' json
我得到了输出
{
"name": "DB_USERNAME",
"value": "new"
}
但我想要更像就地修改或整个 json 从原来的新值修改,像这样:
{
"taskDefinition": {
"containerDefinitions": [
{
"name": "web",
"image": "my-image",
"environment": [
{
"name": "DB_HOST",
"value": "localhost"
},
{
"name": "DB_USERNAME",
"value": "new"
}
]
}
]
}
}
是否可以使用 jq
或任何已知的解决方法?
谢谢。
已更新
任何想要编辑多值的人,
这是我使用的方法
JQ=""
for e in DB_HOST=rds DB_USERNAME=xxx; do
k=${e%=*}
v=${e##*=}
JQ+="(.taskDefinition.containerDefinitions[0].environment[] | select(.name==\"$k\") | .value) |= \"$v\" | "
done
jq '${JQ%??}' json
我认为应该有更简洁的方法,但这似乎工作正常。
分配给路径就够了,如果你使用|=
,例如
jq '
(.taskDefinition.containerDefinitions[0].environment[] |
select(.name=="DB_USERNAME") | .value) |= "new"
' infile.json
输出:
{
"taskDefinition": {
"containerDefinitions": [
{
"name": "web",
"image": "my-image",
"environment": [
{
"name": "DB_HOST",
"value": "localhost"
},
{
"name": "DB_USERNAME",
"value": "new"
}
]
}
]
}
}
您可能会考虑使用此替代方法 |=
:
walk( if type=="object" and .name=="DB_USERNAME"
then .value="new" else . end)
这是一个 select 的免费解决方案,使用 |=
:
.taskDefinition.containerDefinitions[0].environment |=
map(if .name=="DB_USERNAME" then .value = "new"
else . end)
在 |=
的 LHS 表达式中避免 select
使解决方案更稳健 w.r.t。正在使用的 jq 版本。
以防万一,我有一个原始的 json 如下所示:
{
"taskDefinition": {
"containerDefinitions": [
{
"name": "web",
"image": "my-image",
"environment": [
{
"name": "DB_HOST",
"value": "localhost"
},
{
"name": "DB_USERNAME",
"value": "user"
}
]
}
]
}
}
我想就地修改匹配键的值,如下所示:
jq '.taskDefinition.containerDefinitions[0].environment[] | select(.name=="DB_USERNAME") | .value="new"' json
我得到了输出
{
"name": "DB_USERNAME",
"value": "new"
}
但我想要更像就地修改或整个 json 从原来的新值修改,像这样:
{
"taskDefinition": {
"containerDefinitions": [
{
"name": "web",
"image": "my-image",
"environment": [
{
"name": "DB_HOST",
"value": "localhost"
},
{
"name": "DB_USERNAME",
"value": "new"
}
]
}
]
}
}
是否可以使用 jq
或任何已知的解决方法?
谢谢。
已更新
任何想要编辑多值的人, 这是我使用的方法
JQ=""
for e in DB_HOST=rds DB_USERNAME=xxx; do
k=${e%=*}
v=${e##*=}
JQ+="(.taskDefinition.containerDefinitions[0].environment[] | select(.name==\"$k\") | .value) |= \"$v\" | "
done
jq '${JQ%??}' json
我认为应该有更简洁的方法,但这似乎工作正常。
分配给路径就够了,如果你使用|=
,例如
jq '
(.taskDefinition.containerDefinitions[0].environment[] |
select(.name=="DB_USERNAME") | .value) |= "new"
' infile.json
输出:
{
"taskDefinition": {
"containerDefinitions": [
{
"name": "web",
"image": "my-image",
"environment": [
{
"name": "DB_HOST",
"value": "localhost"
},
{
"name": "DB_USERNAME",
"value": "new"
}
]
}
]
}
}
您可能会考虑使用此替代方法 |=
:
walk( if type=="object" and .name=="DB_USERNAME"
then .value="new" else . end)
这是一个 select 的免费解决方案,使用 |=
:
.taskDefinition.containerDefinitions[0].environment |=
map(if .name=="DB_USERNAME" then .value = "new"
else . end)
在 |=
的 LHS 表达式中避免 select
使解决方案更稳健 w.r.t。正在使用的 jq 版本。