这是我的测试数据:
[
{
"id": "id-1",
"tags": {
"key": "name",
"value": "name-1"
}
},
{
"id": "id-2"
}
]
我试图简化输出,以显示'名称'字段,如果存在,并始终显示ID。例如,这个脚本几乎可以工作:
~ $ cat testdata | jq '.[] | {id, name: .tags.value}'
{
"id": "id-1",
"name": "name-1"
}
{
"id": "id-2",
"name": null
}
当我尝试添加针对.keys不存在的警示并过滤“'键的部分'我关心,发生了什么:
~ $ cat testdata | jq '.[] | {id, name: (select(.tags.key == "name") | .tags.value)}'
{
"id": "id-1",
"name": "name-1"
}
我认为{}以某种方式结束了零长度数组,而不是' null'。我该怎么用而不是|?我误解了什么?
答案 0 :(得分:0)
我最终使用[POSSIBLY_MATCHED_EXPRESSION][0]
来解决问题,在这种情况下:
cat testdata | jq '.[] | {id, name: ([select(.tags.key == "name") | .tags.value][0])}'
答案 1 :(得分:0)
如果我理解正确,如果您只想包含名称,请执行以下操作:
map({id} + with_entries(select(.key == "tags") | .value))
否则,如果您不介意null
名称:
map({id, name: with_entries(select(.key == "tags") | .value) | .name})
如果您有其他"标签,那么这是一个更通用的解决方案。所以它不是硬编码只接受name
值。
这假设任何对象值实际上是键/值对。
map(with_entries(if .value | type == "object" then .value else . end))
或者tags
是唯一的动态属性:
map(with_entries(if .key == "tags" then .value else . end))
答案 2 :(得分:0)
如果目标是产生:
{"id":"id-1","name":"name-1"}
{"id":"id-2"}
那么以下三个表达式基本上是等价的解决方案:
.[] | if .tags.key == "name" then {id, name: .tags.value} else {id} end
.[] | {id} + (if .tags.key == "name" then {name: .tags.value} else {} end)
.[] | (select(.tags.key == "name") | {id, name: .tags.value}) // {id}
答案 3 :(得分:0)
你可以添加
| if .name == null then del(.name) else . end
到过滤器的末尾,以便在其值为null
时删除.name键。
使用您的测试数据,以下
.[]
| {id, name:.tags.value }
| if .name == null then del(.name) else . end
产生
{
"id": "id-1",
"name": "name-1"
}
{
"id": "id-2"
}