I have the following json that I need to parse values in a bash script.
{
"matrix-2h44ka21lln62": {
"projectId": "app-54934",
"matrixId": "matrix-2h44ka21lln62",
"state": "FINISHED",
"gcsPath": "App-ios-runner/2023-02-07_13-55-43.444360_CdCC/shard_0",
"webLink": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4663013071689981858/details",
"downloaded": true,
"billableMinutes": {
"virtual": 0,
"physical": 1
},
"clientDetails": {
"Flank Version": "v23.01.0",
"Flank Revision": "7ad3d5ba4097f189965110ca52b93fd0645715e0"
},
"gcsPathWithoutRootBucket": "2023-02-07_13-55-43.444360_CdCC/shard_0",
"gcsRootBucket": "App-ios-runner",
"axes": [
{
"device": "iphone8-15.7-en-portrait",
"outcome": "failure",
"details": "0 test cases failed",
"suiteOverview": {
"total": 0,
"errors": 0,
"failures": 0,
"flakes": 0,
"skipped": 0,
"elapsedTime": 0,
"overheadTime": 0
}
}
],
"appFileName": "App-UISmokeTests.zip",
"testFileName": "App-UISmokeTests_iphoneos16.2-arm64_shard_0.xctestrun",
"isCompleted": false,
"testExecutions": [
{
"id": "matrix-2h44ka21lln62_execution-clgfpxn2zgrta",
"modelId": "iphone8",
"deviceVersion": "15.7",
"state": "FINISHED",
"errorMessage": "",
"progress": [
"Starting attempt 1.",
"Checking Internet connection...",
"Internet connection stable!",
"Starting iOS test.",
"Completed iOS test.",
"Done. Test time = 14 (secs)",
"Starting results processing. Attempt: 1",
"Completed results processing. Time taken = 3 (secs)"
],
"toolResultsStep": {
"executionId": "4663013071689981858",
"historyId": "bh.388190097b1eab25",
"projectId": "app-54934",
"stepId": "bs.2b9b72bccab868fa"
}
}
],
"testTimeout": 2700,
"isRoboTest": false,
"historyId": "",
"executionId": "",
"invalidMatrixDetails": "UNKNOWN",
"outcome": "failure"
},
"matrix-8hj1qx8udleaa": {
"projectId": "app-54934",
"matrixId": "matrix-8hj1qx8udleaa",
"state": "FINISHED",
"gcsPath": "App-ios-runner/2023-02-07_13-55-43.444360_CdCC/shard_1",
"webLink": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/5654175129805154564/details",
"downloaded": true,
"billableMinutes": {
"virtual": 0,
"physical": 1
},
"clientDetails": {
"Flank Version": "v23.01.0",
"Flank Revision": "7ad3d5ba4097f189965110ca52b93fd0645715e0"
},
"gcsPathWithoutRootBucket": "2023-02-07_13-55-43.444360_CdCC/shard_1",
"gcsRootBucket": "App-ios-runner",
"axes": [
{
"device": "iphone8-15.7-en-portrait",
"outcome": "failure",
"details": "0 test cases failed",
"suiteOverview": {
"total": 0,
"errors": 0,
"failures": 0,
"flakes": 0,
"skipped": 0,
"elapsedTime": 0,
"overheadTime": 0
}
}
],
"appFileName": "App-UISmokeTests.zip",
"testFileName": "App-UISmokeTests_iphoneos16.2-arm64_shard_1.xctestrun",
"isCompleted": false,
"testExecutions": [
{
"id": "matrix-8hj1qx8udleaa_execution-10jy4hq8i62g4",
"modelId": "iphone8",
"deviceVersion": "15.7",
"state": "FINISHED",
"errorMessage": "",
"progress": [
"Starting attempt 1.",
"Checking Internet connection...",
"Internet connection stable!",
"Starting iOS test.",
"Completed iOS test.",
"Done. Test time = 15 (secs)",
"Starting results processing. Attempt: 1",
"Completed results processing. Time taken = 4 (secs)"
],
"toolResultsStep": {
"executionId": "5654175129805154564",
"historyId": "bh.388190097b1eab25",
"projectId": "app-54934",
"stepId": "bs.b7d2f90beed6230a"
}
}
],
"testTimeout": 2700,
"isRoboTest": false,
"historyId": "",
"executionId": "",
"invalidMatrixDetails": "UNKNOWN",
"outcome": "failure"
},
"matrix-2i6y9uq9i0ext": {
"projectId": "app-54934",
"matrixId": "matrix-2i6y9uq9i0ext",
"state": "FINISHED",
"gcsPath": "App-ios-runner/2023-02-07_13-55-43.444360_CdCC/shard_2",
"webLink": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4958041021718608851/details",
"downloaded": true,
"billableMinutes": {
"virtual": 0,
"physical": 1
},
"clientDetails": {
"Flank Version": "v23.01.0",
"Flank Revision": "7ad3d5ba4097f189965110ca52b93fd0645715e0"
},
"gcsPathWithoutRootBucket": "2023-02-07_13-55-43.444360_CdCC/shard_2",
"gcsRootBucket": "App-ios-runner",
"axes": [
{
"device": "iphone8-15.7-en-portrait",
"outcome": "failure",
"details": "0 test cases failed",
"suiteOverview": {
"total": 0,
"errors": 0,
"failures": 0,
"flakes": 0,
"skipped": 0,
"elapsedTime": 0,
"overheadTime": 0
}
}
],
"appFileName": "App-UISmokeTests.zip",
"testFileName": "App-UISmokeTests_iphoneos16.2-arm64_shard_2.xctestrun",
"isCompleted": false,
"testExecutions": [
{
"id": "matrix-2i6y9uq9i0ext_execution-1zvntyq5awzyv",
"modelId": "iphone8",
"deviceVersion": "15.7",
"state": "FINISHED",
"errorMessage": "",
"progress": [
"Starting attempt 1.",
"Checking Internet connection...",
"Internet connection stable!",
"Starting iOS test.",
"Completed iOS test.",
"Done. Test time = 13 (secs)",
"Starting results processing. Attempt: 1",
"Completed results processing. Time taken = 5 (secs)"
],
"toolResultsStep": {
"executionId": "4958041021718608851",
"historyId": "bh.388190097b1eab25",
"projectId": "app-54934",
"stepId": "bs.283070cfe31b0c"
}
}
],
"testTimeout": 2700,
"isRoboTest": false,
"historyId": "",
"executionId": "",
"invalidMatrixDetails": "UNKNOWN",
"outcome": "failure"
}
}
I went with jq to parse these results but I'm stuck on how to iterate values over the output of my jq command
jq -c --raw-output '.[] | {matrixId: .matrixId, state: .state, details: .axes[].details, device: .axes[].device, webLink: .webLink} | to_entries | map({key:.key, value:.value})'
I want to get the following result
[
{
"key": "matrixId",
"value": "matrix-2h44ka21lln62"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4663013071689981858/details"
}
],
[
{
"key": "matrixId",
"value": "matrix-8hj1qx8udleaa"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/5654175129805154564/details"
}
],
[
{
"key": "matrixId",
"value": "matrix-2i6y9uq9i0ext"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4958041021718608851/details"
}
]
It returns the output as three array objects with no comma separated value which is blocking me on iterating over them
I tried to search on how can I join them through piping but it's not working as expected
.[]
iterates over the elements in an array and returns a stream of elements. So the input [1,2,3]
will be returned as 1 2 3
when filtered through .[]
.
Now you could stream the array's elements, apply a transformation, and then collect them again: [.[] | f]
, but hold on. There's a better way: map(f)
.
Applying this idea to your program gives:
jq -c 'map({matrixId, state, details: .axes[].details, device: .axes[].device, webLink} | to_entries[])'
(Not sure why you have to_entries | map({key:.key, value:.value})
, because to_entries
already returns objects of that form.)
Output:
[
{
"key": "matrixId",
"value": "matrix-2h44ka21lln62"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4663013071689981858/details"
},
{
"key": "matrixId",
"value": "matrix-8hj1qx8udleaa"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/5654175129805154564/details"
},
{
"key": "matrixId",
"value": "matrix-2i6y9uq9i0ext"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4958041021718608851/details"
}
]
If you want an array of arrays, then don't iterate to_entries
and simply map to the entries array:
jq 'map({matrixId, state, details: .axes[].details, device: .axes[].device, webLink} | to_entries)'
Output:
[
[
{
"key": "matrixId",
"value": "matrix-2h44ka21lln62"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4663013071689981858/details"
}
],
[
{
"key": "matrixId",
"value": "matrix-8hj1qx8udleaa"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/5654175129805154564/details"
}
],
[
{
"key": "matrixId",
"value": "matrix-2i6y9uq9i0ext"
},
{
"key": "state",
"value": "FINISHED"
},
{
"key": "details",
"value": "0 test cases failed"
},
{
"key": "device",
"value": "iphone8-15.7-en-portrait"
},
{
"key": "webLink",
"value": "https://console.firebase.google.com/project/app-54934/testlab/histories/bh.388190097b1eab25/matrices/4958041021718608851/details"
}
]
]