我是最近才开始使用jq的,我想知道是否甚至可以使用这种方法。
示例:
{
"name": "device",
"version": "1.0.0",
"address": [
{
"address": "10.1.2.3",
"interface": "wlan1_wifi"
},
{
"address": "10.1.2.5",
"interface": "wlan2_link"
},
{
"address": "10.1.2.4",
"interface": "ether1"
}
],
"wireless": [
{
"name": "wlan1_wifi",
"type": "5Ghz",
"ssid": "wifi"
},
{
"name": "wlan2_link",
"type": "2Ghz",
"ssid": "link"
}
]
}
首先让我们将示例转换为该json对象:
cat json | jq '. | {"name": ."name", "version": ."version", "wireless": [."wireless"[] | {"name": ."name", "type": ."type", "ssid": ."ssid"}]}'
{
"name": "device",
"version": "1.0.0",
"wireless": [
{
"name": "wlan1_wifi",
"type": "5Ghz",
"ssid": "wifi"
},
{
"name": "wlan2_link",
"type": "2Ghz",
"ssid": "link"
}
]
}
现在有问题。我需要为"wireless"
数组分配一个地址。该地址存储在"address"
数组中。
所以问题是:有一种方法可以基于"address"
(在无线阵列中)和“ "name"
(在地址阵列中)在interface"
中找到正确的json对象为"wireless"
数组中的每个json对象,然后为其分配"address"
?
最终结果应如下所示:
{
"name": "device",
"version": "1.0.0",
"wireless": [
{
"name": "wlan1_wifi",
"type": "5Ghz",
"ssid": "wifi",
"address": "10.1.2.3"
},
{
"name": "wlan2_link",
"type": "2Ghz",
"ssid": "link",
"address": "10.1.2.5"
}
]
}
答案:
这是我基于@peak的answer的答案。而不是复制.wireless
的内容然后再使用map
,而是选择只想包含的键。这也使我可以随意定位“地址”。
(INDEX(.address[]; .interface)) as $dict
| {name: .name, version: .version,
wireless: [.wireless[] | {name, address: ($dict[.name]|.address), type, ssid}]}
答案 0 :(得分:2)
以下内容将按照最初的请求生成输出:
(.wireless[].name) as $name
| .address[]
| select(.interface == $name)
| { wireless: {name: $name, address}}
但是,上述过滤器可能会产生多个结果,因此您可能需要相应地进行修改。
如果您的jq具有INDEX/2
(仅在jq 1.5发布后才可用),则可以简单地使用它来创建查找表:
(INDEX(.address[]; .interface)) as $dict
| {name,
version,
wireless: (.wireless
| map(. + {address: ($dict[.name]|.address) }) ) }
或者(可能取决于确切的要求):
(INDEX(.address[]; .interface)) as $dict
| del(.address)
| .wireless |= map(. + {address: ($dict[.name]|.address) })
如果您的jq没有INDEX/2
,那么您可以轻松地改写上面的内容(使用reduce
),甚至可以更容易地从https://github.com/stedolan/jq/blob/master/src/builtin.jq中获取INDEX/2
的定义。