json - 如何使用公共密钥合并和附加两个 json 文件而不丢失其他数据
问题描述
我有两个 json 文件,其中有几个 json 对象。我想通过使用 jq 和 group_by(.id) 在 linux 上合并两个 json 文件实际上我不需要使用 jq 但我需要制作 linux shell 脚本文件。
当然,我尝试了许多解决方案,但它们的工作方式并不完全符合我的要求。
输入1:file1.json
{"id":"1234", "branch": "master", "arr":["say", "one", "more"]}
{"id":"102", "branch": "master", "arr":["yes"]}
{"id":"1228", "branch": "master"}
输入2:file2.json
{"id":"1234", "branch": "dev", "other": "value", "arr":["what"]}
{"id":"102", "branch": "dev"}
{"id":"0806", "branch": "master"}
我期望的是
{"id":"1234", "branch": ["master", "dev"], "other": "value", "arr":["say", "one", "more", "what"]}
{"id":"102", "branch": ["master", "dev"], "arr":["yes"]}
{"id":"1228", "branch": "master"}
{"id":"0806", "branch": "master"}
但实际输出就像
{"id":"1234", "branch": "dev", "other": "value", "arr":["what"]}
{"id":"102", "branch": "dev"}
{"id":"0806", "branch": "master"}
解决方案
在下文中,我们使用通用函数combine
来组合两个对象,定义如下。
使用此函数,并使用如下调用:
jq -n -f combine.jq --slurpfile f1 file1.json --slurpfile f2 file2.json
并假设您的 jq 有INDEX/2
,那么只需编写以下内容即可获得解决方案:
INDEX( $f1[]; .id) as $d1
| INDEX( $f2[]; .id) as $d2
| reduce (($d1+$d2)|keys_unsorted)[] as $id
({}; .[$id] = ($d1[$id] | combine($d2[$id])) )
| .[]
也就是我们为这两个文件中的每一个构造一个字典,然后在对应的key处组合对象,然后产生想要的流。
如果您的 jq 安装没有INDEX/2
,那么现在是升级的好时机,但另一种方法是从 builtin.jq 复制其 def(请参阅下面的“评论”)。
结合/1
在下文中,针对 jq 1.5 或更高版本,组合值的细节留给内部函数aggregate
.
# Combine . with obj using aggregate/2 for shared keys whose values differ
def combine($obj):
# Combine two entities in an array-oriented fashion:
# if both are arrays: a + b
# else if a is an array: a + [b]
# else if b is an array: [a] + b
# else [a, b]
def aggregate(a; b):
if (a|type) == "array" then
if (b|type) == "array" then a + b
else a + [b]
end
else
if (b|type) == "array" then [a] + b
else [a, b]
end
end;
if . == null then $obj
elif $obj == null then .
else reduce ($obj|keys_unsorted[]) as $key (.;
if .[$key] == $obj[$key] then .
else .[$key] = if has($key) and ($obj|has($key))
then aggregate( .[$key]; $obj[$key] )
else .[$key] + $obj[$key]
end
end )
end ;
推荐阅读
- swift - 使用 Firebase / Xcode 重新验证用户时出错(用于用户电子邮件更新)
- java - 登录 Spring Boot - REST 控制器和 WebClient
- sql - 如何在 SQL 中创建季度(会计年度)临时表
- spring-boot - 应用程序启动异常后记录
- ms-access - 有没有办法从表中的 OLEObject 字段中提取 AutoCAD 绘图和图片?
- while-loop - 在添加文件夹项目时处理不允许 if 语句 AppleScript
- angular - 使用角度 7 设置背景 img
- c# - 运行任务列表时出现 System.ArgumentOutOfRangeException
- python-3.x - 如何从 CSV 文件中删除“/5”
- sql - 我想使用合并更新表,我的表源将使用交叉连接