首页 > 解决方案 > jq 递归更新某些元素的值

问题描述

下面的 JSON 数据的目的是用 的所有元素内的值更新字段dst的值,而不管树内的深度如何,同时保留数据的整个结构。srctype t

这可能jq吗?我的几次尝试归结为以下无法达到预期目的的命令:

$ jq -r 'map_values(select(.. | .type? == "t" |= (.dst = .src)))'

{
    "a": "b",
    "c": [
        {
            "type": "t",
            "src": "xx",
            "dst": "zz"
        },
        {
            "type": "t",
            "src": "xx",
            "dst": "zz"
        }
    ],
    "d": [
        {
            "e": [
                {
                    "type": "t",
                    "src": "xx",
                    "dst": "zz"
                }
            ]
        },
        {
            "type": "t2",
            "src": "xx",
            "dst": "zz"
        }
     ]
}

标签: jsonrecursioneditjq

解决方案


用jq可以吗?

jq 是图灵完备的 :-)

这是一个简单的解决方案:

walk( if type == "object" and .type == "t" then .dst = .src else . end)

如果您的 jq 没有walk/1,那么可能是升级(到 jq 1.6)的好时机;否则,您可以从网上获取其定义,例如通过谷歌搜索:jq "def walk"

或者 ...

reduce paths as $x (.;
    if (getpath($x)|.type? // false) == "t"
    then setpath( $x + ["dst"]; getpath( $x + ["src"] ))
    else . end)

推荐阅读