用 JQ 修改嵌套的 JSON 数组
modify nested JSON array with JQ
我想用JQ修改以下JSON输入:
{
"rows": [
{
"fields": [
{
"name": "id",
"value": "k1"
},
{
"name": "val",
"value": "2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d308ea329718"
},
{
"name": "Encoding",
"value": "hex"
}
]
},
{
"fields": [
{
"name": "id",
"value": "k2"
},
{
"name": "val",
"value": "2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d308ea329718"
},
{
"name": "Encoding",
"value": "hex"
}
]
}
]
}
以便将名称为 "Encoding"
的 "value"
字段的 "hex"
值修改为 "oct"
only包含 .name=="id" and .value=="k1"
.
字段的行
我该怎么做?我可以 select
一个带有 .value=="k1"
等的字段,但我似乎无法找到一种方法 "go up the tree" 随后更新 "Encoding"
字段。
不能期望输入具有固定的 field/row 顺序。
使用 any/2
生成一个 jq 过滤器,与问题的英文描述非常匹配:
.rows |= map( if any(.fields[]; .name=="id" and .value=="k1")
then .fields |= map(if .name == "Encoding"
then .value = "oct"
else .
end)
else .
end )
使用when/2
如果我们使用如下定义的方便的通用函数,则可能会出现稍微不那么冗长且可能更清晰的解决方案:
def when(filter; action): if (filter?) // null then action else . end;
然后我们可以简单地写成:
.rows[] |= when( any(.fields[]; .name=="id" and .value=="k1");
.fields |= map( when (.name == "Encoding";
.value = "oct")))
注意事项
- 在将其更改为 "oct".
之前,您可能需要检查 .value == "hex" 是否
- 上述过滤器可能会在每个 "row".
中改变一对以上 name/value 对
我想用JQ修改以下JSON输入:
{
"rows": [
{
"fields": [
{
"name": "id",
"value": "k1"
},
{
"name": "val",
"value": "2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d308ea329718"
},
{
"name": "Encoding",
"value": "hex"
}
]
},
{
"fields": [
{
"name": "id",
"value": "k2"
},
{
"name": "val",
"value": "2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d308ea329718"
},
{
"name": "Encoding",
"value": "hex"
}
]
}
]
}
以便将名称为 "Encoding"
的 "value"
字段的 "hex"
值修改为 "oct"
only包含 .name=="id" and .value=="k1"
.
我该怎么做?我可以 select
一个带有 .value=="k1"
等的字段,但我似乎无法找到一种方法 "go up the tree" 随后更新 "Encoding"
字段。
不能期望输入具有固定的 field/row 顺序。
使用 any/2
生成一个 jq 过滤器,与问题的英文描述非常匹配:
.rows |= map( if any(.fields[]; .name=="id" and .value=="k1")
then .fields |= map(if .name == "Encoding"
then .value = "oct"
else .
end)
else .
end )
使用when/2
如果我们使用如下定义的方便的通用函数,则可能会出现稍微不那么冗长且可能更清晰的解决方案:
def when(filter; action): if (filter?) // null then action else . end;
然后我们可以简单地写成:
.rows[] |= when( any(.fields[]; .name=="id" and .value=="k1");
.fields |= map( when (.name == "Encoding";
.value = "oct")))
注意事项
- 在将其更改为 "oct". 之前,您可能需要检查 .value == "hex" 是否
- 上述过滤器可能会在每个 "row". 中改变一对以上 name/value 对