如何使用 JQ 更新 JSON 并获取更新后的值
How to update JSON using JQ and get the updated value
我在 JSON 中有一些数据,我想使用 JQ 对其进行编辑。
- 这是一个人员列表。
- 每人可拥有一个或多个
mobile
。
- 每个
mobile
都有一个number
(这显然是唯一的)并且没有。 calls
制作。
- 还有人跟踪
total
次通话(他们拥有的每个手机的通话总和)
我在这里尝试使用自解释变量。数据不够清楚还请大家指教
[
{
"name": "Person1",
"mobiles": [{
"number": "11111",
"calls": 2
},{
"number": "22222",
"calls": 3
}],
"total": 5
},
{
"name": "Person2",
"mobiles": [{
"number": "33333",
"calls": 1
},{
"number": "44444",
"calls": 2
},{
"number": "55555",
"calls": 1
}],
"total": 4
}
]
我想要的是,给定一个手机号码,没有。在特定日期为该手机拨打的电话数,更新 json(更新个人计数器和总数)
例如。假设拨打的号码 444444
是 5,那么最后的 json 应该是
[
{
"name": "Person1",
"mobiles": [{
"number": "11111",
"calls": 2
},{
"number": "22222",
"calls": 3
}],
"total": 5
},
{
"name": "Person2",
"mobiles": [{
"number": "33333",
"calls": 1
},{
"number": "44444",
"calls": 7 // previous value was 2, added 5 more
},{
"number": "55555",
"calls": 1
}],
"total": 9 // previous total was 4, added 5 more
}
]
到目前为止我尝试了什么
我可以更新 total
个电话,但不能更新给定号码的个人电话
map(select(.mobiles[].number == "44444").total = .total + 5)
给出
[
{
"name": "Person1",
"mobiles": [
{
"number": "11111",
"calls": 2
},
{
"number": "22222",
"calls": 3
}
],
"total": 5
},
{
"name": "Person2",
"mobiles": [
{
"number": "33333",
"calls": 1
},
{
"number": "44444",
"calls": 2 // How do I update this
},
{
"number": "55555",
"calls": 1
}
],
"total": 9 // This is correct
}
]
按照您正在探索的方向更新相关的 "calls":
map( (.mobiles[] | select(.number == $number) | .calls) += $incr)
其中 $number 和 $incr 的值可以(例如)在命令行上指定,例如
jq --arg number 44444 --argjson incr 5 -f update.jq input.json
要更新相关 "total",您可以使用 any/2
:
map( if any(.mobiles[]; .number == $number)
then .total += $incr
else .
end)
您可以将这两个链接在一起,无论是字面意思,还是(可能更有效)将两个过滤器组合成一个 map
。为了可读性和可维护性,您可能还想定义辅助函数(即,使用 def
)。
我在 JSON 中有一些数据,我想使用 JQ 对其进行编辑。
- 这是一个人员列表。
- 每人可拥有一个或多个
mobile
。 - 每个
mobile
都有一个number
(这显然是唯一的)并且没有。calls
制作。 - 还有人跟踪
total
次通话(他们拥有的每个手机的通话总和)
我在这里尝试使用自解释变量。数据不够清楚还请大家指教
[
{
"name": "Person1",
"mobiles": [{
"number": "11111",
"calls": 2
},{
"number": "22222",
"calls": 3
}],
"total": 5
},
{
"name": "Person2",
"mobiles": [{
"number": "33333",
"calls": 1
},{
"number": "44444",
"calls": 2
},{
"number": "55555",
"calls": 1
}],
"total": 4
}
]
我想要的是,给定一个手机号码,没有。在特定日期为该手机拨打的电话数,更新 json(更新个人计数器和总数)
例如。假设拨打的号码 444444
是 5,那么最后的 json 应该是
[
{
"name": "Person1",
"mobiles": [{
"number": "11111",
"calls": 2
},{
"number": "22222",
"calls": 3
}],
"total": 5
},
{
"name": "Person2",
"mobiles": [{
"number": "33333",
"calls": 1
},{
"number": "44444",
"calls": 7 // previous value was 2, added 5 more
},{
"number": "55555",
"calls": 1
}],
"total": 9 // previous total was 4, added 5 more
}
]
到目前为止我尝试了什么
我可以更新 total
个电话,但不能更新给定号码的个人电话
map(select(.mobiles[].number == "44444").total = .total + 5)
给出
[
{
"name": "Person1",
"mobiles": [
{
"number": "11111",
"calls": 2
},
{
"number": "22222",
"calls": 3
}
],
"total": 5
},
{
"name": "Person2",
"mobiles": [
{
"number": "33333",
"calls": 1
},
{
"number": "44444",
"calls": 2 // How do I update this
},
{
"number": "55555",
"calls": 1
}
],
"total": 9 // This is correct
}
]
按照您正在探索的方向更新相关的 "calls":
map( (.mobiles[] | select(.number == $number) | .calls) += $incr)
其中 $number 和 $incr 的值可以(例如)在命令行上指定,例如
jq --arg number 44444 --argjson incr 5 -f update.jq input.json
要更新相关 "total",您可以使用 any/2
:
map( if any(.mobiles[]; .number == $number)
then .total += $incr
else .
end)
您可以将这两个链接在一起,无论是字面意思,还是(可能更有效)将两个过滤器组合成一个 map
。为了可读性和可维护性,您可能还想定义辅助函数(即,使用 def
)。