I have two JSON files:
$ 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"
}
and want to merge them into a single file (think of file 1 as "template" and file 2 as "actual values"). I don’t want to merge all properties, I only want to transfer some properties of the second file (specifically only version
and dependencies
). version
should overwrite the value in the original file and dependencies
should be added to the new file. name
must not be overwritten and the original name must be kept.
This is the expected result:
{
"id": "ZGVhZGJlZWY=",
"name": "first file",
"version": 2,
"description": "just a simple json file",
"dependencies": [
4,
2
]
}
I know that jq supports the +
and *
operators to merge or merge recursively, but how can I apply those to only some properties and not all? How can I access both files in my jq program; do I have to preprocess the file and then use --arg
in a second jq call?
Obviously, jq '. + {version, dependencies}' a.json b.json
does not work. What is the correct program here?
What would the solution look like if description
should also be dropped from the output?
2
Answers
+
or*
can be used here, correct. Let's first see how+
works:Perfect, now how to get the objects from two unrelated files?
--slurpfile
can be used, which reads all JSON entities in the file into an array and puts it into a variable.We are getting closer, but are not quite there yet.
name
is overwritten andcomment
is added; both of which we do not want. To solve this, we can transform the slurped object into a new object which only contains the properties we care aboutNow let's address part two of the question: "can some properties of the first file be dropped?"
There are basically two options:
{id,name} + ($b[0] | {version,dependencies})
del(.description) + ($b[0] | {version,dependencies})
or. + ($b[0] | {version,dependencies}) | del(.description)
Depending on the number of properties you want to keep/drop, one or the other solution might be simpler to use. Creating a new object has the advantage of being able to rename properties in one go.
Executing solution 2:
If you want simplicity, brevity, and efficiency, consider:
If the first file might have .dependencies, and if in that case you want to add in the second file’s:
To drop .description, you could append
| del(.description)
to either of these filters.