【问题标题】:Interaction between {} and select{} 和 select 之间的交互
【发布时间】:2014-07-27 04:18:10
【问题描述】:

这是我的测试数据:

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

【问题讨论】:

    标签: jq


    【解决方案1】:

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

     cat testdata | jq '.[] | {id, name: ([select(.tags.key == "name") | .tags.value][0])}'
    

    【讨论】:

      【解决方案2】:

      如果我理解正确,如果您只想包含一个存在的名称,我会这样做:

      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))
      

      【讨论】:

      • 示例数据包含在问题中——我不确定你在想什么,因为这对我来说毫无意义。不过,我实际上只关心“名称”值。 [编辑问题以澄清过滤器是故意的]
      • 我只是说,如果您显示的数据是真实数据的高度简化版本。如果有更多属性、其他“标签”等等,这可以处理您的任何情况。
      【解决方案3】:

      如果目标是生产:

      {"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}
      

      【讨论】:

        【解决方案4】:

        你可以添加

        | 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"
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-06
          • 2016-11-11
          • 2016-05-15
          • 2015-03-31
          • 2014-06-28
          • 2015-07-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多