使用 jq 从 JSON 文件中删除和添加键值
Removing and adding key-value from JSON file using jq
我有一个 json 文件如下-
{
"key1": [
"value1"
],
"key2": [
"value2"
],
"key3": [
"value3"
],
"key4": {
"name": "value4"
},
"key5": [
{
"field1": "abc",
"field2": "xyz"
}
]
}
我想从 key5 数组中删除字段 2 并使用 jq 在 key5 数组中添加另一个字段 field3
我尝试了各种方法,但无法弄清楚如何在单个命令中执行此操作。
你能帮忙吗?提前致谢
这假设插入和删除键(field2
和 field3
)也是动态的,而不仅仅是插入的值。
- 使用
--arg
和 --argjson
使用过滤器外部的值初始化变量,这里 field2
作为字符串,{"field3": "new"}
作为 JSON 对象
- 在要更改的元素上使用更新运算符
|=
,此处为 .key5[]
。
- 注意:
.key5
是数组,不是对象,因此没有字段。但是数组确实包含对象作为它的元素。使用 .key5[]
访问数组元素将更新数组中的 all 个对象。要只更新其中一个,比如第一个,请改用 .key[0]
。
- 使用
delpaths
删除给定路径,这里是top-level字段[$delkey]
。
- 使用简单的加法
+
添加一个新的 key/value 对作为对象,这里 $add
.
jq --arg delkey 'field2' --argjson addobj '{"field3": "new"}' '
.key5[] |= delpaths([[$delkey]]) + $addobj
' input.json
{
"key1": [
"value1"
],
"key2": [
"value2"
],
"key3": [
"value3"
],
"key4": {
"name": "value4"
},
"key5": [
{
"field1": "abc",
"field3": "new"
}
]
}
如果您想单独提供新对象的键和值,即作为字符串,而不是 pre-composed JSON,您需要第三个输入变量
jq --arg delkey 'field2' --arg addkey 'field3' --arg addval 'new' '
.key5[] |= (delpaths([[$delkey]]) | .[$addkey] = $addval)
' input.json
.key5[] |= ( ... )
允许您修改在 .key5
.
处找到的数组的每个元素
其中,我们可以使用常用的命令来删除和添加字段。
jq '.key5[] |= ( del( .field2 ) | .field3 = "foo" )'
Demo jqplay
这是一个变体,其中要添加的值作为 command-line 参数提供:
jq --arg val foo '.key5[] |= ( del( .field2 ) | .field3 = $val )'
尝试过滤:
del(.key5[0].field2) | .key5[0] |= .+{field3:"foo"}
输出:
{
"key1": [
"value1"
],
"key2": [
"value2"
],
"key3": [
"value3"
],
"key4": {
"name": "value4"
},
"key5": [
{
"field1": "abc",
"field3": "foo"
}
]
}
演示
我有一个 json 文件如下-
{
"key1": [
"value1"
],
"key2": [
"value2"
],
"key3": [
"value3"
],
"key4": {
"name": "value4"
},
"key5": [
{
"field1": "abc",
"field2": "xyz"
}
]
}
我想从 key5 数组中删除字段 2 并使用 jq 在 key5 数组中添加另一个字段 field3 我尝试了各种方法,但无法弄清楚如何在单个命令中执行此操作。 你能帮忙吗?提前致谢
这假设插入和删除键(field2
和 field3
)也是动态的,而不仅仅是插入的值。
- 使用
--arg
和--argjson
使用过滤器外部的值初始化变量,这里field2
作为字符串,{"field3": "new"}
作为 JSON 对象 - 在要更改的元素上使用更新运算符
|=
,此处为.key5[]
。- 注意:
.key5
是数组,不是对象,因此没有字段。但是数组确实包含对象作为它的元素。使用.key5[]
访问数组元素将更新数组中的 all 个对象。要只更新其中一个,比如第一个,请改用.key[0]
。
- 注意:
- 使用
delpaths
删除给定路径,这里是top-level字段[$delkey]
。 - 使用简单的加法
+
添加一个新的 key/value 对作为对象,这里$add
.
jq --arg delkey 'field2' --argjson addobj '{"field3": "new"}' '
.key5[] |= delpaths([[$delkey]]) + $addobj
' input.json
{
"key1": [
"value1"
],
"key2": [
"value2"
],
"key3": [
"value3"
],
"key4": {
"name": "value4"
},
"key5": [
{
"field1": "abc",
"field3": "new"
}
]
}
如果您想单独提供新对象的键和值,即作为字符串,而不是 pre-composed JSON,您需要第三个输入变量
jq --arg delkey 'field2' --arg addkey 'field3' --arg addval 'new' '
.key5[] |= (delpaths([[$delkey]]) | .[$addkey] = $addval)
' input.json
.key5[] |= ( ... )
允许您修改在 .key5
.
其中,我们可以使用常用的命令来删除和添加字段。
jq '.key5[] |= ( del( .field2 ) | .field3 = "foo" )'
Demo jqplay
这是一个变体,其中要添加的值作为 command-line 参数提供:
jq --arg val foo '.key5[] |= ( del( .field2 ) | .field3 = $val )'
尝试过滤:
del(.key5[0].field2) | .key5[0] |= .+{field3:"foo"}
输出:
{
"key1": [
"value1"
],
"key2": [
"value2"
],
"key3": [
"value3"
],
"key4": {
"name": "value4"
},
"key5": [
{
"field1": "abc",
"field3": "foo"
}
]
}
演示