代码之家  ›  专栏  ›  技术社区  ›  CodeManX

jq-返回所有具有与条件匹配的子属性的顶级属性键

jq
  •  1
  • CodeManX  · 技术社区  · 6 年前

    {
      "foo": {
        "restricted": true
      },
      "bar": {
        "restricted": false
      },
      "baz": { }
    }
    

    作为单线:

    {"foo":{"restricted":true},"bar":{"restricted":false},"baz":{}}
    

    我想得到返回的所有顶级属性键 restricted == false restricted 子属性。对于上面的示例JSON,预期的输出是:

    "bar"
    "baz"
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   CodeManX    6 年前

    我想出了以下的表达方式:

    jq "to_entries[] | select(.value.restricted|not) | .key"

    to_entries 将顶级对象转换为具有 "key" "value"

    [
      {
        "key": "foo135",
        "value": {
          "restricted": true
        }
      },
      {
        "key": "foo246",
        "value": {
          "restricted": false
        }
      },
      {
        "key": "foo345",
        "value": {}
      }
    ]
    

    [] 分解此数组。这样做是为了在下一步中过滤单个对象:

    {
      "key": "foo135",
      "value": {
        "restricted": true
      }
    }
    {
      "key": "foo246",
      "value": {
        "restricted": false
      }
    }
    {
      "key": "foo345",
      "value": {}
    }
    

    然后对每个对象应用过滤器: select(.value.restricted|not) . 使用子属性过滤掉属性 restricted .value.restricted |not 选择对象的步骤 restricted == false 以及使用单个条件不具有此属性的对象:

    {
      "key": "foo246",
      "value": {
        "restricted": false
      }
    }
    {
      "key": "foo345",
      "value": {}
    }
    

    “钥匙” 属性已选定: .key . 这将返回匹配对象(最初是顶级属性键)的名称:

    "foo246"
    "foo345"
    

    | 在里面 select(...) | .key 不是严格需要的。结果是一样的没有。

    如果需要字符串数组作为结果。。。

    [
      "foo246",
      "foo345"
    ]
    

    jq "to_entries | map(select(.value.restricted|not).key)"
    

    如你所见, select() map() 过滤掉单个元素,甚至可以与属性过滤器结合使用 .键 .

    [] 最后就像 map(...)[] ,然后数组被分解,结果又是一个字符串列表,就像在初始示例中一样,但使用的方法稍有不同。