如何使用jq合并json文件?
我在shell脚本中使用jq工具(jqjson处理器)来解析json 我有2个json文件,想把它们合并成一个唯一的文件 以下是文件的内容: 文件1:如何使用jq合并json文件?,json,jq,Json,Jq,我在shell脚本中使用jq工具(jqjson处理器)来解析json 我有2个json文件,想把它们合并成一个唯一的文件 以下是文件的内容: 文件1: {"tag_id" : ["t1"], "inst_id" : "s1"} {"tag_id" : ["t1"], "inst_id" : "s2"} 文件2: {"tag_id" : ["t2"], "inst_id" : "s1"} {"tag_id" : ["t2"], "inst_id" : "s2"} {"tag_id" : ["t2
{"tag_id" : ["t1"], "inst_id" : "s1"}
{"tag_id" : ["t1"], "inst_id" : "s2"}
文件2:
{"tag_id" : ["t2"], "inst_id" : "s1"}
{"tag_id" : ["t2"], "inst_id" : "s2"}
{"tag_id" : ["t2"], "inst_id" : "s3"}
预期结果:
{"tag_id" : ["t1","t2"], "inst_id" : "s1"}
{"tag_id" : ["t1","t2"], "inst_id" : "s2"}
{"tag_id" : ["t2"], "inst_id" : "s3"}
一种方法是使用
group\u by
:
jq -n --slurpfile file1 file1.json --slurpfile file2 file2.json -f merge.jq
其中merge.jq包含:
def sigma(f): reduce f as $x (null; . + $x);
$file1 + $file2
| group_by(.inst_id)[]
| {tag_id: sigma(.[].tag_id), inst_id: .[0].inst_id }
这里有一种类似联接的方法。它假定jq具有
索引/2
,并支持--slurpfile
命令行选项。如果你的jq没有这些,现在是升级的好时机,尽管有一些简单的解决方法
调用
join.jq
以下方法在这方面非常有效: (a) 它利用了file1.json和file2.json是对象流这一事实,从而避免了将这些对象存储为数组所需的内存 (b) 它避免了排序(例如,按
分组\u按
)
关键概念是按键添加对象。为了在流中执行按键添加对象,我们定义了以下通用函数:
# s is assumed to be a stream of mutually
# compatible objects in the sense that, given
# any key of any object, the values at that key
# must be compatible w.r.t. `add`
def keywise_add(s):
reduce s as $x ({};
reduce ($x|keys_unsorted)[] as $k (.;
.[$k] += $x[$k]));
现在可以按如下方式完成任务:
keywise_add(inputs | {(.inst_id): .tag_id} )
| keys_unsorted[] as $k
| {tag_id: .[$k], inst_id: $k}
调用
使用add.jq中的上述程序,调用:
jq -c -n -f add.jq file1.json file2.json
收益率:
{"tag_id":["t1","t2"],"inst_id":"s1"}
{"tag_id":["t1","t2"],"inst_id":"s2"}
{"tag_id":["t2"],"inst_id":"s3"}
警告
以上假设inst_id
是字符串值。如果不是这样,那么只要inst_id | tostring
之间没有冲突,就仍然可以使用上述方法,例如,如果inst_id
始终是数字
jq -c -n -f add.jq file1.json file2.json
{"tag_id":["t1","t2"],"inst_id":"s1"}
{"tag_id":["t1","t2"],"inst_id":"s2"}
{"tag_id":["t2"],"inst_id":"s3"}