jq如何合并两个json文件的内容
如何把一个json文件的内容合并入另一个json文件。例如:
$ cat source.json
{
"expiretime": "36000",
"keyStore": "/tmp/kvs",
"logger": {
"default": {
"appenders": [
"console"
],
"level": "info"
}
},
"request-timeout": 30000
}
$ cat target.json
{
"expiretime": "6000",
"keyStore": "/tmp/kvs"
}
假设我们有上述两个json文件;我们的目标是把source.json里面的两个字段logger和request-timeout合并到target.json文件里面。
$ jq --argjson s "$(<source.json)" '.logger = $s.logger | ."request-timeout" = $s."request-timeout"' target.json
{
"expiretime": "6000",
"keyStore": "/tmp/kvs",
"logger": {
"default": {
"appenders": [
"console"
],
"level": "info"
}
},
"request-timeout": 30000
}
几点说明:
- --argson 把source.json的内如读出来($(<filename)是shell的重定向),然后以s作为alias,后面直接使用$s引用即可。
- $s就是指的是source.json的内容
- 如果字段名含有特殊符号,例如"-",那么需要用双引号括起来,"request-timeout"。
另一个例子,把一个文件的内容全部插入到另一个文件的字段。
例如把target.json插入到source.json的.logger.config
字段:
$ jq --argjson s "$(<target.json)" '.logger.config = $s' source.json
{
"expiretime": "36000",
"keyStore": "/tmp/kvs",
"logger": {
"default": {
"appenders": [
"console"
],
"level": "info"
},
"config": {
"expiretime": "6000",
"keyStore": "/tmp/kvs"
}
},
"request-timeout": 30000
}
第三个例子,source不是从文件中读取,而是直接从变量中获取
for (( i=0; i<5; i++ )); do
vm=$(echo "{}" | jq '.ip="'${VMIPS[$i]}'" | .hostname="'${VMNAMES[$i]}'"')
instance=$(echo $instance | jq --argjson s "$vm" '.vm[.vm|length]=$s')
done
echo $instance | jq .
一个instance包含多个vm,每一个vm有属性主机名和IP地址;上述代码含义是对每一个vm生成一个object对象,然后把object对象插入到instance的vm数组成员里面。