json 使用jq删除嵌套数组

kx1ctssn  于 2023-02-06  发布在  其他
关注(0)|答案(4)|浏览(218)

这是我的数据结构:

[
    {
        "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= name 1,删除name= name 4的嵌套数组对象,并想保留对象的其余部分。我尝试使用map(select),但这只会给予我完整的对象。是否可以在特定的子数组上使用del,并保持其余部分不变?
结果应该是这下面.另外我想要避免枚举所有属性保留在外部对象:

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

有什么主意吗?谢谢!

voj3qocg

voj3qocg1#

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

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

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

qacovj5a

qacovj5a2#

您可以使用以下命令,它将仅删除"name": "name4"阵列。

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

oknrviil3#

下面是使用选择减少tostreamdelpaths的解决方案

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

ao218c7q4#

我采用了与@peak类似的方法,但将其颠倒,因此,我们选择不需要的内容并删除,而不是选择您想要的内容并在输出中进行设置。

[path(.organizations[0].spaces[]| select(.name == "name4")] as $trash | delpaths($trash)

相关问题