Jq: 为对象中的每个条目打印键和值

我如何让 JQ这样带着 json:

{
"host1": { "ip": "10.1.2.3" },
"host2": { "ip": "10.1.2.2" },
"host3": { "ip": "10.1.18.1" }
}

并产生这个输出:

host1, 10.1.2.3
host2, 10.1.2.2
host3, 10.1.18.1

我对格式不感兴趣,我只是不知道如何访问键名和值。

134172 次浏览

要获得作为流的顶级键,可以使用 内置功能keys[]。所以解决你这个问题的一个办法就是:

jq -r 'keys[] as $k | "\($k), \(.[$k] | .ip)"'

keys按照排序顺序生成键名; 如果希望按照原始顺序生成键名,请使用 keys_unsorted

另一种按原始顺序生成密钥的方法是:

jq -r 'to_entries[] | "\(.key), \(.value | .ip)"'

CSV 和 TSV 输出

@ csv 和@tsv 过滤器也值得在这里考虑,例如。

jq -r 'to_entries[] | [.key, .value.ip] | @tsv'

生产:

host1   10.1.2.3
host2   10.1.2.2
host3   10.1.18.1

嵌入对象

如果按照下面的示例嵌入感兴趣的键,则必须按照所示的代码行修改 jq 过滤器。

输入:

{
"myhosts": {
"host1": { "ip": "10.1.2.3" },
"host2": { "ip": "10.1.2.2" },
"host3": { "ip": "10.1.18.1" }
}
}

修改:

jq -r '.myhosts | keys[] as $k | "\($k), \(.[$k] | .ip)"'

遇到了非常优雅的解决方案

jq 'with_entries(.value |= .ip)'

输出

{
"host1": "10.1.2.3",
"host2": "10.1.2.2",
"host3": "10.1.18.1"
}

下面是要使用的 jqplay 代码片段: https://jqplay.org/s/Jb_fnBveMQ

函数 with_entries将对象列表中的每个对象转换为键/值对,因此我们可以分别访问 .key.value,我们使用 update |=操作符用字段 .ip更新(覆盖)每个 KV 项 .value