1

我想从i3-msg -t get_treewith中提取包含焦点窗口的子树jq。我知道可以找到焦点窗口

i3-msg -t get_tree | jq ".. | (.nodes? // empty)[] | select(.focused == true)"

一个简单的例子是:

{
  "node": [
    {
      "node": {
        "foo": "bar"
      }
    },
    {
      "node": {
        "foo": "foo"
      }
    }
  ]
}

如果搜索node包含.foo == "bar"应该返回输出应该

{
  "node": [
    {
      "node": {
        "foo": "bar"
      }
    }
  ]
}

但我似乎找不到合适的方法来提取从根跨越到该节点的子树。

4

2 回答 2

2
.node |= map(select(.node.foo == "bar"))

这个概念被称为更新分配

于 2020-04-06T22:12:19.920 回答
2

原始问题有两个不同的子问题,一个与使用相关,..但未参考已发布的 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. 否则,如果null插入数组中的值通过setpath保留原结构方面,请参见下面的附录

(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像以前一样添加调用即可;另见下面的附录

附录

如果不需要为了保留原始结构而null可能插入到数组中的值,最简单的方法是将原始 JSON 中的值更改为某个独特的值(例如“:null:”),执行选择,修剪值,然后然后将独特的值转换回. setpathnullnullnull

例子

例如,考虑 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)
于 2020-04-08T21:03:53.567 回答