如何使用 yq select 基于子键值的所有 YAML 键?

How to select all YAML keys based on a subkey value using yq?

我有一个像这样的 YAML 文件:

$ yq '.' test.yaml
{
  "entries": {
    "entry1": {
      "enabled": true
    },
    "entry2": {
      "enabled": false
    },
    "entry3": {
      "dummy": "TEST"
    }
  }
}

我想 select 所有具有 enabled 属性的条目设置为 true:

$ yq '.entries | select(.[].enabled==true)' test.yaml
                         ^  ^
                         |  |
                         |  --- with enabled attribute set to true
                         ------ all entries

我希望输出是

{
  "entry1": {
    "enabled": true
  }
}

但我得到

{
  "entry1": {
    "enabled": true
  },
  "entry2": {
    "enabled": false
  },
  "entry3": {
    "dummy": "TEST"
  }
}

我做错了什么?

诀窍是将对象转换为数组,将选择应用于数组元素,然后将其转换回对象。过滤器 with_entries 在后台进行这些转换。它是 to_entries | map(foo) | from_entries 的 shorthand(参见 jq manual)。

根据所使用的 yq 实现,调用略有不同:yq - Python or yq - Go。 bash 脚本包含对这两种实现的调用。

#!/bin/bash

INPUT='
{
  "entries": {
    "entry1": {
      "enabled": true
    },
    "entry2": {
      "enabled": false
    },
    "entry3": {
      "dummy": "TEST"
    }
  }
}
'

echo "yq - Go implementation"       # https://mikefarah.github.io/yq/
yq -j e '.entries | with_entries(select(.value.enabled == true))' - <<< "$INPUT"

echo "yq - Python implementation"   # https://github.com/kislyuk/yq
yq '.entries | with_entries(select(.value.enabled == true))' <<< "$INPUT"

输出

{
  "entry1": {
    "enabled": true
  }
}