ted*_*edx 8 arrays merge json object jq
我有两个 json 文件,orig.json 和 patch.json,它们具有相似的格式。
原件.json:
{
"a": {
"a1": "original a1",
"a2": "original a2",
"list": ["baz", "bar"]
},
"b": "original value B"
}
Run Code Online (Sandbox Code Playgroud)
补丁.json:
{
"a": {
"a1": "patch a1",
"list": ["foo"]
},
"c": "original c"
}
Run Code Online (Sandbox Code Playgroud)
目前我正在使用jq递归合并它们。但是,jq 对列表的默认行为只是重新分配。jq 使用的示例输出$ jq -s '.[0] * .[1]' orig.json patch.json:
{
"a": {
"a1": "patch a1",
"a2": "original a2",
"list": [
"foo"
]
},
"b": "original value B",
"c": "original c"
}
Run Code Online (Sandbox Code Playgroud)
请注意,a.list现在等于 patch.json 的a.list。我希望新a.list的是 orig.json 的列表和 patch.json 的列表合并。换句话说,我想a.list等于["baz", "bar", "foo"].
有没有一种方法可以用 jq 轻松地做到这一点,也许是通过覆盖数组的默认合并策略?
$ jq -s 'def deepmerge(a;b):
reduce b[] as $item (a;
reduce ($item | keys_unsorted[]) as $key (.;
$item[$key] as $val | ($val | type) as $type | .[$key] = if ($type == "object") then
deepmerge({}; [if .[$key] == null then {} else .[$key] end, $val])
elif ($type == "array") then
(.[$key] + $val | unique)
else
$val
end)
);
deepmerge({}; .)' file1.json file2.json > merged.json
Run Code Online (Sandbox Code Playgroud)
这是一个通用函数,它通过在同一位置连接数组来递归组合两个复合 JSON 实体:
# Recursively meld a and b,
# concatenating arrays and
# favoring b when there is a conflict
def meld(a; b):
a as $a | b as $b
| if ($a|type) == "object" and ($b|type) == "object"
then reduce ([$a,$b]|add|keys_unsorted[]) as $k ({};
.[$k] = meld( $a[$k]; $b[$k]) )
elif ($a|type) == "array" and ($b|type) == "array"
then $a+$b
elif $b == null then $a
else $b
end;
Run Code Online (Sandbox Code Playgroud)
将 $orig 设置为 orig.json 的内容并将 $patch 设置为 patch.json 的内容:
{
"a": {
"a1": "patch a1",
"a2": "original a2",
"list": [
"baz",
"bar",
"foo"
]
},
"b": "original value B",
"c": "original c"
}
Run Code Online (Sandbox Code Playgroud)
调用:
jq -f patch.jq --argfile patch patch.json orig.json
Run Code Online (Sandbox Code Playgroud)
其中 patch.jq 包含:
(.a.list + $patch.a.list) as $a
| . + $patch
| .a.list = $a
Run Code Online (Sandbox Code Playgroud)
产生:
{
"a": {
"a1": "patch a1",
"list": [
"baz",
"bar",
"foo"
]
},
"b": "original value B",
"c": "original c"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1304 次 |
| 最近记录: |