【问题标题】:Delete on nested array with jq使用 jq 删除嵌套数组
【发布时间】:2017-02-13 23:12:40
【问题描述】:

这是我的数据结构:

[
    {
        "name": "name1",
        "organizations": [
            {
                "name": "name2",
                "spaces": [
                    {
                        "name": "name3",
                        "otherkey":"otherval"
                    },
                    {
                        "name": "name4",
                        "otherkey":"otherval"
                    }
                ]
            }
        ]
    },
    {
        "name": "name21",
        "organizations": [
            {
                "name": "name22",
                "spaces": [
                    {
                        "name": "name23",
                        "otherkey":"otherval"
                    },
                    {
                        "name": "name24",
                        "otherkey":"otherval"
                    }
                ]
            }
        ]
    }
]

我只想保留 name=name1,删除 name=name4 的嵌套数组对象,并希望保持对象的其余部分完好无损。我尝试使用 map(select) 但这只会给我完整的对象。是否可以在特定子数组上使用 del 并保持其余部分不变?

结果应该如下。此外,我想避免枚举所有属性以保留在外部对象上:

[
    {
        "name": "name1",
        "organizations": [
            {
                "name": "name2",
                "spaces": [
                    {
                        "name": "name3",
                        "otherkey":"otherval"
                    }
                ]
            }
        ]
    }
]

有什么想法吗?谢谢!

【问题讨论】:

    标签: arrays json nested jq


    【解决方案1】:

    一个非常有针对性的解决方案是:

    path(.[0].organizations[0].spaces) as $target
    | (getpath($target) | map(select(.name != "name4"))) as $new
    | setpath($target; $new)
    

    如果允许,您可以考虑:

    walk(if type == "object" and .spaces|type == "array"
         then .spaces |= map(select(.name != "name4"))
         else . end)
    

    或:

    del(.. | .spaces? // empty | .[] | select(.name == "name4") )
    

    (如果你的 jq 没有walk/1,那么它的 jq 定义很容易通过谷歌搜索找到。)

    【讨论】:

      【解决方案2】:

      这是一个使用 selectreducetostreamdelpaths

      的解决方案
      map(  
          select(.name == "name1")
        | reduce (tostream|select(length==2)) as [$p,$v] (
            .
          ; if [$p[-1],$v] == ["name","name4"] then delpaths([$p[:-1]]) else . end
          )
      )
      

      【讨论】:

        【解决方案3】:

        您可以使用下面的,它只会删除"name": "name4" 数组。

        jq 'del(.[] | .organizations? | .[] | .spaces?|.[] | select(.name? == "name4"))' yourJsonFile.json
        

        【讨论】:

          猜你喜欢
          • 2023-03-05
          • 2017-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-02
          • 2021-05-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多