如何获取包含已知对象的 json 的子树
How to get subtree of json containing known object
我想用 jq
从 i3-msg -t get_tree
中提取包含焦点 window 的子树。我知道重点 window 可以通过
找到
i3-msg -t get_tree | jq ".. | (.nodes? // empty)[] | select(.focused == true)"
一个简单的例子是:
{
"node": [
{
"node": {
"foo": "bar"
}
},
{
"node": {
"foo": "foo"
}
}
]
}
如果搜索包含 .foo == "bar"
的 node
,则输出应该 return
{
"node": [
{
"node": {
"foo": "bar"
}
}
]
}
但我似乎找不到合适的方法来提取从根到该节点的子树。
.node |= map(select(.node.foo == "bar"))
这个概念被称为Update assignment
原始问题有两个不同的子问题,一个与 ..
的使用有关,但未参考发布的 JSON 示例,另一个基于特定类型的 JSON 输入。此响应使用基于使用 paths
的策略:
reduce pv as [$p,$v] (null; setpath($p; $v))
这可能会或可能不会按需要处理数组,部分取决于需要什么。如果通常不需要数组中的 null
值,则按如下方式添加对 walk/1
的调用是合适的:
walk(if type == "array" then map(select(. != null)) else . end)
或者,如果必须保留原件中存在的 null
值,则可以使用下面 附录 中详述的策略。
(1) 使用..
表征的问题
def pv:
paths as $p
| getpath($p)
| . as $v
| (.nodes? // empty)[] | select(.focused == true)
| [$p,$v];
reduce pv as [$p,$v] (null; setpath($p; $v))
如上所述,要消除所有数组中的所有空值,您可以添加对 walk/1
的调用。否则,如果 setpath
将 null
值插入数组以保留原始结构的各个方面,请参阅下面的 附录 。
(2) 对于样本JSON,满足以下条件:
def pv:
paths as $p
| getpath($p)
| . as $v
| (.node? // empty) | select(.foo == "bar")
| [$p,$v];
reduce pv as [$p,$v] (null; setpath($p; $v))
对于给定的样本,这会产生:
{"node":[{"node":{"foo":"bar"}}]}
对于类似的输入,如果要从数组中删除 null
值,只需像以前一样附加对 walk/1
的调用;另请参阅下面的附录。
附录
如果不需要 setpath
可能插入数组以保留原始结构的 null
值,最简单的方法是更改原始 [=66] 中的 null
值=] 到某个独特的值(例如“:null:”),执行选择,trim null
值,然后将独特的值转换回 null
。
例子
例如,考虑 foo/bar 示例的这个变体:
{
"node": [
{
"node": {
"foo": "foo0"
}
},
{
"node": {
"foo": "bar",
"trouble": [
null,
1,
null
]
}
},
{
"node": {
"foo": "foo1"
}
},
{
"node": {
"foo": "bar",
"trouble": [
1,
2,
3
]
}
}
],
"nodes": [
{
"node": {
"foo": "foo0"
}
},
{
"node": {
"foo": "bar",
"trouble": [
null,
1,
null
]
}
}
]
}
使用“:null:”作为区别值,可以使用先前针对此案例显示的 "main" 程序的以下变体:
walk(if type == "array" then map(if . == null then ":null:" else . end) else . end)
| reduce pv as [$p,$v] (null; setpath($p; $v))
| walk(if type == "array"
then map(select(. != null) | if . == ":null:" then null else . end)
else . end)
我想用 jq
从 i3-msg -t get_tree
中提取包含焦点 window 的子树。我知道重点 window 可以通过
i3-msg -t get_tree | jq ".. | (.nodes? // empty)[] | select(.focused == true)"
一个简单的例子是:
{
"node": [
{
"node": {
"foo": "bar"
}
},
{
"node": {
"foo": "foo"
}
}
]
}
如果搜索包含 .foo == "bar"
的 node
,则输出应该 return
{
"node": [
{
"node": {
"foo": "bar"
}
}
]
}
但我似乎找不到合适的方法来提取从根到该节点的子树。
.node |= map(select(.node.foo == "bar"))
这个概念被称为Update assignment
原始问题有两个不同的子问题,一个与 ..
的使用有关,但未参考发布的 JSON 示例,另一个基于特定类型的 JSON 输入。此响应使用基于使用 paths
的策略:
reduce pv as [$p,$v] (null; setpath($p; $v))
这可能会或可能不会按需要处理数组,部分取决于需要什么。如果通常不需要数组中的 null
值,则按如下方式添加对 walk/1
的调用是合适的:
walk(if type == "array" then map(select(. != null)) else . end)
或者,如果必须保留原件中存在的 null
值,则可以使用下面 附录 中详述的策略。
(1) 使用..
表征的问题def pv:
paths as $p
| getpath($p)
| . as $v
| (.nodes? // empty)[] | select(.focused == true)
| [$p,$v];
reduce pv as [$p,$v] (null; setpath($p; $v))
如上所述,要消除所有数组中的所有空值,您可以添加对 walk/1
的调用。否则,如果 setpath
将 null
值插入数组以保留原始结构的各个方面,请参阅下面的 附录 。
(2) 对于样本JSON,满足以下条件:
def pv:
paths as $p
| getpath($p)
| . as $v
| (.node? // empty) | select(.foo == "bar")
| [$p,$v];
reduce pv as [$p,$v] (null; setpath($p; $v))
对于给定的样本,这会产生:
{"node":[{"node":{"foo":"bar"}}]}
对于类似的输入,如果要从数组中删除 null
值,只需像以前一样附加对 walk/1
的调用;另请参阅下面的附录。
附录
如果不需要 setpath
可能插入数组以保留原始结构的 null
值,最简单的方法是更改原始 [=66] 中的 null
值=] 到某个独特的值(例如“:null:”),执行选择,trim null
值,然后将独特的值转换回 null
。
例子
例如,考虑 foo/bar 示例的这个变体:
{
"node": [
{
"node": {
"foo": "foo0"
}
},
{
"node": {
"foo": "bar",
"trouble": [
null,
1,
null
]
}
},
{
"node": {
"foo": "foo1"
}
},
{
"node": {
"foo": "bar",
"trouble": [
1,
2,
3
]
}
}
],
"nodes": [
{
"node": {
"foo": "foo0"
}
},
{
"node": {
"foo": "bar",
"trouble": [
null,
1,
null
]
}
}
]
}
使用“:null:”作为区别值,可以使用先前针对此案例显示的 "main" 程序的以下变体:
walk(if type == "array" then map(if . == null then ":null:" else . end) else . end)
| reduce pv as [$p,$v] (null; setpath($p; $v))
| walk(if type == "array"
then map(select(. != null) | if . == ":null:" then null else . end)
else . end)