jq根据值更新列表元素

时间:2018-11-11 15:39:00

标签: json jq

是否可以使用jq打开以下JSON数据

[
    {
        "a": null,
        "b": [
            {
                "c": "cc",
                "d": "dd1"
            },
            {
                "c": "cc",
                "d": "dd1",
                "e": "ee",
                "f": "ff"
            }
        ]
    },
    {
        "b": [
            {
                "c": "cc",
                "d": "dd2",
                "e": "ee",
                "f": "ff"
            }
        ]
    }
]

进入

[
    {
        "a": null,
        "b": [
            [
                "cc", "d1"
            ],
            [
                "cc", "d1", "ff"
            ]
        ]
    },
    {
        "b": [
            [
                "cc", "d2", "ff"
            ]
        ]
    }
]

请注意,这样做的目的是根据条件将b列表的某些元素减少。如果d1的值为d,则条件将分配字符串dd1;否则,如果存在d2,则分配dd2

以下未成功的尝试证明了这一想法:

$ jq -r '.[].b[] = [.[].b[].c, ?, .[].b[].f?]'

2 个答案:

答案 0 :(得分:1)

这可能不是执行所需操作的最佳方法,但它确实获得了所需的输出,并且具有您询问的条件。

jq '.[].b |= map(
   [ .c,
     (if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
     .f // empty
   ] )'

答案 1 :(得分:0)

在不更改d键的值的情况下,您将使用以下jq过滤器:

jq '.[].b[]|=(to_entries|map(.value))' file

这会将b数组更新为内部对象的所有值。

如果要更新d,可以使用以下过滤器:

jq '.[].b[] |= (to_entries|
                  map(
                    if(.key=="d") then 
                       .value|=sub("d+";"d") 
                    else . 
                    end
                    |.value)
                )' file

添加了一个检查键是否为d的关联值,以从字符串中删除重复的d字符。这需要jq支持正则表达式(才能使用sub函数)。