我有两个JSON文件:
$ jq . a.json b.json
{
"id": "ZGVhZGJlZWY=",
"name": "first file",
"version": 1,
"description": "just a simple json file"
}
{
"version": 2,
"name": "fake name",
"dependencies": [
4,
2
],
"comment": "I'm just sitting here, ignore me"
}
想把它们合并成一个文件(将文件1视为"模板",将文件2视为"实际值")。我不想合并所有属性,我只想传输第二个文件的一些属性(特别是仅version
和dependencies
)。version
应覆盖原始文件中的值,dependencies
应添加到新文件中。不能覆盖name
,并且必须保留原始名称。
这是预期结果:
{
"id": "ZGVhZGJlZWY=",
"name": "first file",
"version": 2,
"description": "just a simple json file",
"dependencies": [
4,
2
]
}
我知道jq支持+
和*
操作符来合并或递归合并,但是我怎样才能将这些操作符只应用于某些属性而不是全部属性呢?我是否必须预处理文件,然后在第二次jq调用中使用--arg
?
显然,jq '. + {version, dependencies}' a.json b.json
不起作用。这里正确的程序是什么?
如果description
也应该从输出中删除,解决方案会是什么样子?
2条答案
按热度按时间gblwokeq1#
如果您想要简单、简短和高效,请考虑:
如果第一个文件可能具有.dependencies,并且在这种情况下要添加第二个文件的:
要删除.description,可以将
| del(.description)
附加到这两个过滤器中的任何一个。xwbd5t1u2#
这里可以使用
+
或*
,这是正确的。让我们先看看+
是如何工作的:很好,现在如何从两个不相关的文件中获取对象?可以使用
--slurpfile
,它将文件中的所有JSON实体读入一个数组,并将其放入一个变量中。我们越来越接近,但还没有完全达到。
name
被覆盖,comment
被添加;为了解决这个问题,我们可以把吃东西的对象转换成一个只包含我们所关心的属性的新对象现在让我们回答问题的第二部分:“可以删除第一个文件的某些属性吗?”
基本上有两种选择:
1.创建一个只包含所需属性的新对象,然后添加第二个对象(可以忽略第二个文件的任何属性部分,因为无论如何都会添加它):
{id,name} + ($b[0] | {version,dependencies})
1.正在删除不需要的属性:
del(.description) + ($b[0] | {version,dependencies})
或. + ($b[0] | {version,dependencies}) | del(.description)
根据要保留/删除的属性的数量,一个或另一个解决方案可能更易于使用。创建新对象的优点是能够一次重命名属性。
执行方案二: