MODIFIED:
Hello I'm having problems on merging 2 files basically I have 2 json files with this structure:
[
{
"uri": "some/url.feature",
"id": "safety-tests",
"keyword": "Feature",
"name": "Safety Tests",
"description": "Some description",
"line": 2,
"tags": [
{
"name": "@sometag",
"line": 1
}
],
"elements": [
{
"id": "some-element-id",
"keyword": "Scenario Outline",
"name": ": Some scenario name",
"description": "",
"line": 46,
"type": "scenario",
"tags": [
{
"name": "@sometag",
"line": 1
},
{
"name": "@someothertag",
"line": 31
}
],
"before": [
{
"match": {
"location": "some/test/file.rb:201"
},
"result": {
"status": "passed",
"duration": 15000
}
},
{
"match": {
"location": "some/other/file.rb:5"
},
"result": {
"status": "passed",
"duration": 1722192000
}
}
],
"steps": [
{
"keyword": "Given ",
"name": "Some step name",
"line": 46,
"output": [
"Some output"
],
"match": {
"location": "some/other/path/to/other/file.rb:137"
},
"result": {
"status": "passed",
"duration": 989158000
}
},
{
"keyword": "When ",
"name": "some other step",
"line": 46,
"output": [
"WARNING: static wait for 1 seconds."
],
"match": {
"location": "some/other/path/to/other/file.rb:80"
},
"result": {
"status": "passed",
"duration": 2700052000
}
},
{
"keyword": "And ",
"name": "Some other name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:38"
},
"result": {
"status": "passed",
"duration": 954225000
}
},
{
"keyword": "Then ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 38792000
}
},
{
"keyword": "And ",
"name": "And again some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 39268000
}
},
{
"keyword": "And ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 55637000
}
},
{
"keyword": "And ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 38375000
}
},
{
"keyword": "When ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:12"
},
"result": {
"status": "passed",
"duration": 751416000
}
},
{
"keyword": "And ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 28043000
}
},
{
"keyword": "Then ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:20"
},
"result": {
"status": "passed",
"duration": 5204000
}
}
],
"after": [
{
"match": {
"location": "some/other/path/to/other/file.rb:91"
},
"result": {
"status": "passed",
"duration": 20000
}
},
{
"match": {
"location": "some/other/path/to/other/file.rb:52"
},
"result": {
"status": "passed",
"duration": 5585000
}
},
{
"match": {
"location": "some/other/path/to/other/file.rb:27"
},
"result": {
"status": "passed",
"duration": 168146000
}
},
{
"match": {
"location": "some/other/path/to/other/file.rb:428"
},
"result": {
"status": "passed",
"duration": 62000
}
}
]
},
{
"id": "some-element-id",
"keyword": "Scenario Outline",
"name": ": Some scenario name",
"description": "",
"line": 46,
"type": "scenario",
"tags": [
{
"name": "@sometag",
"line": 1
},
{
"name": "@someothertag",
"line": 31
}
],
"before": [
{
"match": {
"location": "some/test/file.rb:201"
},
"result": {
"status": "passed",
"duration": 15000
}
},
{
"match": {
"location": "some/other/file.rb:5"
},
"result": {
"status": "passed",
"duration": 1722192000
}
}
],
"steps": [
{
"keyword": "Given ",
"name": "Some step name",
"line": 46,
"output": [
"Some output"
],
"match": {
"location": "some/other/path/to/other/file.rb:137"
},
"result": {
"status": "passed",
"duration": 989158000
}
},
{
"keyword": "When ",
"name": "some other step",
"line": 46,
"output": [
"WARNING: static wait for 1 seconds."
],
"match": {
"location": "some/other/path/to/other/file.rb:80"
},
"result": {
"status": "passed",
"duration": 2700052000
}
},
{
"keyword": "And ",
"name": "Some other name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:38"
},
"result": {
"status": "passed",
"duration": 954225000
}
},
{
"keyword": "Then ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 38792000
}
},
{
"keyword": "And ",
"name": "And again some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 39268000
}
},
{
"keyword": "And ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 55637000
}
},
{
"keyword": "And ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 38375000
}
},
{
"keyword": "When ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:12"
},
"result": {
"status": "passed",
"duration": 751416000
}
},
{
"keyword": "And ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:2"
},
"result": {
"status": "passed",
"duration": 28043000
}
},
{
"keyword": "Then ",
"name": "Some other step name",
"line": 46,
"match": {
"location": "some/other/path/to/other/file.rb:20"
},
"result": {
"status": "passed",
"duration": 5204000
}
}
],
"after": [
{
"match": {
"location": "some/other/path/to/other/file.rb:91"
},
"result": {
"status": "passed",
"duration": 20000
}
},
{
"match": {
"location": "some/other/path/to/other/file.rb:52"
},
"result": {
"status": "passed",
"duration": 5585000
}
},
{
"match": {
"location": "some/other/path/to/other/file.rb:27"
},
"result": {
"status": "passed",
"duration": 168146000
}
},
{
"match": {
"location": "some/other/path/to/other/file.rb:428"
},
"result": {
"status": "passed",
"duration": 62000
}
}
]
}
]
}
]
where elements can contain any number of objects on either file. These are test results from cucumber so usually file A contains more elements than file B since file B is a re-run of the failed tests in file A.
For example. If on the first pass we ran 100 tests, file A elements array will contain 100 objects of with the format described above. However if from those 100 tests 50 of them failed, file B elements array will contain 50 objects. What I want to do is to overwrite file A elements array with file B's just adding the elements that repeat in both. Something like
if file A had
"elements":[{a:1, b:2, c:3, d:2, e:9, f:4}]
and file B had
"elements":[{d:5}]
I'd like the new file to have
"elements":[{a:1, b:2, c:3, d:5, e:9, f:4}]
So far I've got
jq '.[].elements' path/to/file/b > path/to/new/file
jq --argfile file path/to/new/file '.[].elements += $file' path/to/file/b
That puts together whatever file B contains in the elements array within the elements array in file A but doesn't remove the duplicated object inside of it.
I tried to use unique but no clue on how to use it. Any ideas?
After a few responses here I got
jq --argfile b ~/Desktop/cucumber-rerun.json '.[0].elements[4] *= $b[0].elements[0]' ~/Desktop/cucumber.json
to works since, in my actual example, I knew the element 4 in file A is the one I want to overwrite with the 1 and only element in file B. However that doesn't work for me since both files are autogenerated and the order of the objects is unknown.
I'd like to have a command that sees both files compared them and autodetects repeated objects from A and B and overwrite those in A with those in B