我有一个这种结构的json:
var v = "str";
/** @var v: Number */
v = 5;
我想用jq查询主机名,mac或IPv6。
{
"nodes": {
"60e327ee58a0": {
"nodeinfo": {
"network": {
"mesh": {
"bat0": {
"interfaces": {
"wireless": [
"<mac-address-removed>"
],
"tunnel": [
"<mac-address-removed>"
]
}
}
},
"mac": "<mac removed>",
"addresses": [
"<ipv6 removed>",
"<ipv6 removed>"
]
},
"hardware": {
"model": "TP-Link TL-WR841N/ND v10",
"nproc": 1
},
"software": {
"batman-adv": {
"compat": 15,
"version": "2015.1"
},
"autoupdater": {
"branch": "stable",
"enabled": true
},
"firmware": {
"release": "v2016.1+1.0.1",
"base": "gluon-v2016.1"
},
"status-page": {
"api": 1
},
"fastd": {
"enabled": true,
"version": "v17"
}
},
"hostname": "Antoniusweg12",
"system": {
"site_code": "ffmsd03"
},
"node_id": "60e327ee58a0"
},
"lastseen": "2016-04-14T12:39:04",
"flags": {
"gateway": false,
"online": true
},
"firstseen": "2016-03-16T15:14:04",
"statistics": {
"clients": 1,
"gateway": "de:ad:be:ef:43:02",
"rootfs_usage": 0.6041666666666667,
"loadavg": 0.09,
"uptime": 1822037.41,
"memory_usage": 0.8124737210932025,
"traffic": {
"rx": {
"packets": 50393821,
"bytes": 5061895206
},
"forward": {
"packets": 173,
"bytes": 17417
},
"mgmt_rx": {
"packets": 47453745,
"bytes": 6623785282
},
"tx": {
"packets": 1205695,
"bytes": 173509528,
"dropped": 5683
},
"mgmt_tx": {
"packets": 37906725,
"bytes": 11475209742
}
}
}
},
"30b5c2b042f4": {
<next block...>
大多数示例都不适合这种json结构,因为对象具有索引
提前感谢您的帮助。
答案 0 :(得分:0)
如果您要过滤,则需要深入查看要检查的属性,看它是否符合您的条件。你不能指望给出一个名字,你会神奇地看到你想要的结果。
按主机名搜索,可在每个节点的.nodeinfo.hostname
属性中找到:
$ jq -c --arg hostname "Antoniusweg12" \
'.nodes[] | select(.nodeinfo.hostname == $hostname)' nodes.json
类似地,对于mac地址,它位于.nodeinfo.network.mac
属性:
$ jq -c --arg mac "aa:bb:cc:dd:ee:ff" \
'.nodes[] | select(.nodeinfo.network.mac == $mac)' nodes.json
对于ip地址,它们有一个数组,但在查询中并没有太大的不同。它们位于.nodeinfo.network.addresses
属性:
$ jq -c --arg ip "aaaa:bbbb:cccc:dddd::1" \
'.nodes[] | select(.nodeinfo.network.addresses[] == $ip)' nodes.json
答案 1 :(得分:0)
这是对问题的另一种看法。假设您要查找值为“Antoniusweg12”的所有键“主机名”, 无论键/值组合在何处发生。
以下内容将揭示感兴趣的键/值组合的路径:
POST /accounts/ @controllers.AccountsController.createOneAccount
给定输入JSON的结果:
paths as $p
| select ( $p[-1] == "hostname" and getpath($p) == "Antoniusweg12" )
| $p
如果您想要包含对象的路径,请将最终[
"nodes",
"60e327ee58a0",
"nodeinfo",
"hostname"
]
替换为$p
;如果你想要包含对象本身:$p[0:-1]
答案 2 :(得分:0)
此解决方案可搜索$needle
,addresses
或mac
字段中指定hostname
所在的节点。
"<ipv6 removed>" as $needle # set to whatever you like
| foreach (.nodes|keys[]) as $k (
.
; .
; ( .nodes[$k].nodeinfo.network.addresses?
+ [ .nodes[$k].nodeinfo.network.mac?
, .nodes[$k].nodeinfo.hostname?
]
) as $haystack
| if $haystack | index($needle)
then {($k): .nodes[$k]}
else empty
end
)
编辑:我现在意识到foreach E as $X (.; .; R)
形式的过滤器几乎总是被重写为E as $X | R
所以上面的内容实际上就是
"<ipv6 removed>" as $needle
| (.nodes|keys[]) as $k
| ( .nodes[$k].nodeinfo.network.addresses?
+ [ .nodes[$k].nodeinfo.network.mac?
, .nodes[$k].nodeinfo.hostname?
]
) as $haystack
| if $haystack | index($needle)
then {($k): .nodes[$k]}
else empty
end