我有json:
{
"interfaces": {
"UDPInterface": [
{
"connectTo": {
"1.2.3.4:25925": {
"user": "bob",
"password": "aaaaaaaa",
"publicKey": "foirncnqwpnqwopnqrrvn308g9h4b.k"
},
"4.3.2.1:24970": {
"user": "sam",
"password": "bbbbbbbb",
"publicKey": "v09ervn4uvr78cweyclfirnfuq3c9pwper.k"
},
"1.3.4.2:41872": {
"user": "betty",
"password": "cccccccccc",
"publicKey": "crnn497hg3j34f34uvrnfwmnriuhqrmoweje.k"
}
},
"bind": "0.0.0.0:64660"
},
{
"connectTo": {},
"bind": "[::]:54887"
}
]
}
}
并希望能够使用jq打印基于"用户"的IP地址行的内容。值。我可以接近这个:
jq '.interfaces.UDPInterface[0].connectTo."1.2.3.4:25925" | select(.user | contains("bob"))'
但是,这只给出了1.2.3.4:25925对象的值:
{"user" : "bob", "password" : "aaaaaaaa", "publicKey" : "foirncnqwpnqwopnqrrvn308g9h4b.k"},
当我需要的是整条线:
"1.2.3.4:25925" : {"user" : "bob", "password" : "aaaaaaaa", "publicKey" : "foirncnqwpnqwopnqrrvn308g9h4b.k"},
但是,我无法弄清楚如何在不知道父对象名称的情况下构建这样的表达式(每个IP地址:端口都是唯一的)。
我整天都在反对这一切,而且我们已经能够解决这个问题了。任何帮助将非常感谢!
答案 0 :(得分:0)
“整行”本身不是有效的JSON对象。您可以获得包含与谓词匹配的所有元素的对象;这将是一种方式:
jq '.interfaces.UDPInterface[0].connectTo | with_entries(select(.value.user | contains("bob")))'
您输入的输出将是:
{
"1.2.3.4:25925": {
"user": "bob",
"password": "aaaaaaaa",
"publicKey": "foirncnqwpnqwopnqrrvn308g9h4b.k"
}
}
答案 1 :(得分:0)
这是一个解决方案,它使用 tostream ,选择和 foreach 来枚举带有“user:”bob“的对象的路径并返回那些使用 getpath
获取所需格式的对象foreach ( tostream
| select(length == 2 and .[0][-1] == "user" and .[1] == "bob")
| .[0]
) as $p (
.
; .
; { ($p[-2]): getpath($p[:-1]) }
)
编辑:我现在意识到foreach E as $X (.; .; R)
形式的过滤器几乎总是被重写为E as $X | R
所以上面的内容实际上就是
( tostream | select(length == 2 and .[0][-1] == "user" and .[1] == "bob") | .[0] ) as $p
| { ($p[-2]): getpath($p[:-1]) }