1

这是我的测试数据:

[
  {
    "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”结束。我应该使用什么来代替 |?我有什么误解?

4

4 回答 4

0

我最终使用: 解决了这个问题[POSSIBLY_MATCHED_EXPRESSION][0],在这种情况下:

 cat testdata | jq '.[] | {id, name: ([select(.tags.key == "name") | .tags.value][0])}'
于 2014-07-27T04:49:14.877 回答
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))

或者 iftags是唯一的动态属性:

map(with_entries(if .key == "tags" then .value else . end))
于 2014-07-27T05:44:33.200 回答
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}
于 2015-09-07T02:24:27.877 回答
0

你可以添加

| if .name == null then del(.name) else . end

到过滤器的末尾以摆脱 .name 键,当它的值为null. 使用您的测试数据,以下

  .[]
| {id, name:.tags.value }
| if .name == null then del(.name) else . end

生产

{
  "id": "id-1",
  "name": "name-1"
}
{
  "id": "id-2"
}
于 2017-08-02T17:21:05.257 回答