【问题标题】:jq update list elements based on valuesjq根据值更新列表元素
【发布时间】:2018-11-11 15:39:00
【问题描述】:

是否可以使用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 列表。如果d 的值为dd1,则该条件分配字符串d1,否则如果dd2 存在,则分配d2。

以下不成功的尝试证明了这个想法:

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

【问题讨论】:

  • 到目前为止你尝试了什么?
  • @oguzismail 查看更新后的问题。我不知道如何解决条件部分以及如何单独更新每个元素。

标签: json jq


【解决方案1】:

这可能不是做你想做的最好的方法,但它确实得到了所需的输出,并且它具有你所询问的条件。

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

【讨论】:

  • 完美运行。确实需要这种 if-then-else 逻辑。谢谢!
【解决方案2】:

在不改变 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 函数)。

【讨论】:

    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    相关资源
    最近更新 更多