Parsing parent and child element into a csv using jq - json

I have a big file that has lines as below.
{
"total": 320,
"assets": [
{
"audit": {
"created": {
"date": "2019-09-30T12:38:01.421Z"
},
"updated": {}
},
"organizationId": "12345678",
"id": 211123898,
"name": "groupId:760c47ad-c9f2958be:assetId:8o-api",
"exchangeAssetName": "8O API",
"groupId": "760c47ad-c9f2958be",
"assetId": "8o-api",
"apis": [
{
"audit": {
"created": {
"date": "2019-09-30T12:38:03.139Z"
},
"updated": {
"date": "2020-03-09T21:37:55.745Z"
}
},
"organizationId": "12345678",
"id": 15822364,
"groupId": "760c47ad-c9f2958be",
"assetId": "8o-api",
"assetVersion": "1.0.0",
"productVersion": "v1",
"description": null,
"tags": [],
"order": 1,
"providerId": null,
"deprecated": false,
"lastActiveDate": "2021-01-15T22:43:33.881Z",
"isPublic": false,
"stage": "release",
"lastActiveDelta": 7,
"pinned": false,
"activeContractsCount": 6,
"autodiscoveryInstanceName": "v1:15822364"
}
],
"totalApis": 1,
"autodiscoveryApiName": "groupId:760c47ad-c9f2958be:assetId:8o-api"
},
{
"audit": {
"created": {
"date": "2018-06-22T19:41:35.760Z"
},
"updated": {
"date": "2018-09-13T06:20:51.151Z"
}
},
"organizationId": "760c47ad-c9f2958be",
"id": 210914379,
"name": "hips-ts",
"exchangeAssetName": "hips-ts",
"groupId": "760c47ad-c9f2958be",
"assetId": "hips-ts",
"apis": [
{
"audit": {
"created": {
"date": "2018-06-22T19:41:35.759Z"
},
"updated": {
"date": "2020-03-09T21:37:55.745Z"
}
},
"organizationId": "760c47ad-c9f2958be",
"id": 15470738,
"groupId": "760c47ad-c9f2958be",
"assetId": "hips-ts",
"assetVersion": "1.0.0",
"productVersion": "v1",
"description": null,
"tags": [],
"order": 1,
"providerId": null,
"deprecated": false,
"lastActiveDate": "2021-01-15T22:43:30.004Z",
"endpointUri": null,
"isPublic": false,
"stage": "release",
"lastActiveDelta": 11,
"pinned": false,
"activeContractsCount": 1,
"autodiscoveryInstanceName": "1-test"
}
],
"totalApis": 1,
"autodiscoveryApiName": "hips-ts"
}
]
}
I am trying to use jq to just get the assetId and the activeContractsCount from this in a comma separated way.
So my output for this text should be
8o-api, 6
hips-ts, 1
I tried the following wiht jq jq -r '[.assets[].assetId, .assets[].apis[].activeContractsCount]|#csv' and I tried mapping too but nothing seems to stick.
Can you help me here? Any help is appreciated.

The following will produce exactly two columns, one for the "assetID" and one for the count:
.assets[].apis[]
| [.assetId, .activeContractsCount]
| #csv

I figured it out as soon as I posted the question. But please let me know if there's a better way to do this.
jq -r '.assets[]|[.apis[].assetId, .apis[].activeContractsCount]|#csv'

Related

JSON Parsing a Plain Text File

I have a lot of data I need to parse though.
I need to pull all pid's and price's.
`
[
{
"id": 159817,
"price": "10.69",
"stocked": true,
"store": {
"id": 809,
"nsn": "22036-0",
"pricingSource": "manual",
"lastUpdated": "2022-12-05T15:24:33.908Z"
},
"sharedFields": {
"type": "PRODUCT",
"id": 24549,
"pid": "12079",
"labels": [
{
"type": "default",
"value": "Chicken Sandwich",
"locale": "en"
},
{
"type": "fresh",
"value": "Chicken",
"locale": "en"
},
{
"type": "product_json",
"value": "Chicken",
"locale": "en"
}
],
"calMin": 600,
"calMax": 600,
"lastUpdated": "2021-12-31T13:49:22.794Z"
}
},
{
"id": 159818,
"price": "9.29",
"stocked": true,
"store": {
"id": 809,
"nsn": "22036-0",
"pricingSource": "manual",
"lastUpdated": "2022-12-05T15:24:33.908Z"
},
"sharedFields": {
"type": "PRODUCT",
"id": 25,
"pid": "1",
"labels": [
{
"type": "default",
"value": "Ham Sandwich",
"locale": "en"
},
{
"type": "fresh",
"value": "Ham",
"locale": "en"
}
],
"calMin": 540,
"calMax": 540,
"lastUpdated": "2021-07-09T19:30:00.326Z"
}
}
]
`
and I need to place them into a string like this, but on a scale of 150 products. I'd also need to change "pid" to "productId"
[{ "productId": "46238", "price": 6.09 }, { "productId": "40240", "price": 1.49 }]
I need to add a string before this data, but I'm pretty confident I can figure that part out.
I am pretty open to the easiest suggestion, whether that be VBS, Excel macro, etc.

Check if a key exists and return another key

I need help with jq syntax on how to return the Gitlab job ID if it contains an artifact. The JSON output looks like this (removed a lot of unrelated info from it and added [...]):
[{
"id": 3219589880,
"status": "success",
"stage": "test",
"name": "job_with_no_artifact",
"ref": "main",
"tag": false,
"coverage": null,
"allow_failure": false,
"created_at": "2022-10-24T18:21:25.119Z",
"started_at": "2022-10-24T18:21:25.986Z",
"finished_at": "2022-10-24T18:21:38.464Z",
"duration": 12.478682,
"queued_duration": 0.499786,
"user": {
"id": 123456789,
[...]
},
"commit": {
"id": "5e0e1f287d20daf2036a3ca71c656dce55999265",
[...]
"pipeline": {
"id": 123456789,
[...]
"project": {
"ci_job_token_scope_enabled": false
},
"artifacts": [],
"runner": {
"id": 12270859,
[...]
},
"artifacts_expire_at": null,
"tag_list": []
}, {
"id": 3219589878,
"status": "success",
"stage": "test",
"name": "create_artifact_job_2",
"ref": "main",
"tag": false,
"coverage": null,
"allow_failure": false,
"created_at": "2022-10-24T18:21:25.111Z",
"started_at": "2022-10-24T18:21:25.922Z",
"finished_at": "2022-10-24T18:21:39.090Z",
"duration": 13.168405,
"queued_duration": 0.464364,
"user": {
"id": 123456789,
[...]
},
"commit": {
"id": "5e0e1f287d20daf2036a3ca71c656dce55999265",
[...]
},
"pipeline": {
"id": 675641982,
[...],
"project": {
"ci_job_token_scope_enabled": false
},
"artifacts_file": {
"filename": "artifacts.zip",
"size": 223
},
"artifacts": [{
"file_type": "archive",
"size": 223,
"filename": "artifacts.zip",
"file_format": "zip"
}, {
"file_type": "metadata",
"size": 153,
"filename": "metadata.gz",
"file_format": "gzip"
}],
"runner": {
"id": 12270845,
[...]
},
"artifacts_expire_at": "2022-10-25T18:21:35.859Z",
"tag_list": []
}, {
"id": 3219589876,
"status": "success",
"stage": "test",
"name": "create_artifact_job_1",
"ref": "main",
"tag": false,
"coverage": null,
"allow_failure": false,
"created_at": "2022-10-24T18:21:25.103Z",
"started_at": "2022-10-24T18:21:25.503Z",
"finished_at": "2022-10-24T18:21:41.407Z",
"duration": 15.904028,
"queued_duration": 0.098837,
"user": {
"id": 123456789,
[...]
},
"commit": {
"id": "5e0e1f287d20daf2036a3ca71c656dce55999265",
[...]
},
"pipeline": {
"id": 123456789,
[...]
},
"web_url": "WEB_URL",
"project": {
"ci_job_token_scope_enabled": false
},
"artifacts_file": {
"filename": "artifacts.zip",
"size": 217
},
"artifacts": [{
"file_type": "archive",
"size": 217,
"filename": "artifacts.zip",
"file_format": "zip"
}, {
"file_type": "metadata",
"size": 152,
"filename": "metadata.gz",
"file_format": "gzip"
}],
"runner": {
"id": 12270857,
},
"artifacts_expire_at": "2022-10-25T18:21:37.808Z",
"tag_list": []
}]
I've been trying to do either of the following using jQ:
Either:
Check if artifacts_file key exists in each iteration and if it does return the (job) id (so .[].id)
Check if artifacts array is empty in each iteration and if it is empty return the (job) id.
In both cases I'm able to do the first part but I am not sure how to return the .id key.
Related stackoverflow questions that I've been trying to utilize and adapt to my case:
jq - return array value if its length is not null
How to check for presence of 'key' in jq before iterating over the values
What I have so far: jq '[.[].artifacts[]|select(length > 0)] | .[]' which returns all the artifacts found (but it doesn't contain the .id of the job).
Checking the existence of a field using has:
.[] | select(has("artifacts_file")).id
3219589878
3219589876
Demo
Checking if a field is an empty array by comparing it to []:
.[] | select(.artifacts == []).id
3219589880
Demo

How to print nested JSON array data in a tabular format?

I want to read the status of clusters and servers inside it.
Below is the sample json file
"data": [{
"id": 7865,
"timeCreated": 1602589399294,
"timeUpdated": 1602748892149,
"name": "gw-ext-1",
"type": "CLUSTER",
"status": "RUNNING",
"multicastEnabled": false,
"primaryNodeId": 546,
"servers": [{
"id": 768,
"timeCreated": 1602589028419,
"timeUpdated": 1602747941321,
"name": "gw-jpg208765-1",
"type": "SERVER",
"serverType": "GATEWAY",
"status": "RUNNING",
"addresses": [{
"networkInterface": "eng123"
},
{
"networkInterface": "eng124"
}],
"clusterId": 098,
"clusterName": "gw-ext-1",
"currentClusteringPort": 897,
"runtimeInformation": {
"Information": {
"runtime": {
"name": "abctech",
"version": "1.6.8"
},
"specification": {
"vendor": "rrr",
"name": "rrrt",
"version": "1.8.89"
}
},
"osInformation": {
"name": "LX",
"version": "35",
"architecture": "klh"
},
"mExpirationDate": 098765589283662
}
},
{
"id": 876,
"timeCreated": 1602589007370,
"timeUpdated": 1602748894901,
"name": "gw-jpg208765-2",
"type": "SERVER",
"serverType": "GATEWAY",
"mVersion": "3.9.1",
"gaVersion": "3.9.1",
"agentVersion": "1.9.5",
"ExpirationDate": 32521996800000,
"ExpirationDate": 1665661007000,
"status": "DISCONNECTED",
"addresses": [{
"networkInterface": "engg"
},
{
"networkInterface": "engg"
}],
"clusterId": 768,
"clusterName": "gw-ext-1",
"serverPort": 987,
"currentClusteringPort": 987,
"runtimeInformation": {
"abcInfo": {
"runtime": {
"name": "abc",
"version": "1.2.3"
},
"specification": {
"vendor": "RRR",
"name": "RTR",
"version": "1.8.0"
}
},
"osInformation": {
"name": "LX",
"version": "4.78",
"architecture": "eng"
},
"ExpirationDate": 8765478999765
}
}],
"visibilityMap": {
"mapNodes": [{
"serverId": 765,
"visibleNodeIds": [765,
876],
"unknownNodeIps": []
},
{
"serverId": 876,
"visibleNodeIds": [765,
876],
"unknownNodeIps": []
}]
}
},
{
"id": 7865,
"timeCreated": 1602589399294,
"timeUpdated": 1602748892149,
"name": "gw-ext-2",
"type": "CLUSTER",
"status": "RUNNING",
"multicastEnabled": false,
"primaryNodeId": 546,
"servers": [{
"id": 768,
"timeCreated": 1602589028419,
"timeUpdated": 1602747941321,
"name": "gw-jpg208766-1",
"type": "SERVER",
"serverType": "GATEWAY",
"status": "RUNNING",
"addresses": [{
"networkInterface": "eng123"
},
{
"networkInterface": "eng124"
}],
"clusterId": 098,
"clusterName": "gw-ext-2",
"currentClusteringPort": 897,
"runtimeInformation": {
"Information": {
"runtime": {
"name": "abctech",
"version": "1.6.8"
},
"specification": {
"vendor": "rrr",
"name": "rrrt",
"version": "1.8.89"
}
},
"osInformation": {
"name": "LX",
"version": "35",
"architecture": "klh"
},
"mExpirationDate": 098765589283662
}
},
{
"id": 876,
"timeCreated": 1602589007370,
"timeUpdated": 1602748894901,
"name": "gw-jpg208766-2",
"type": "SERVER",
"serverType": "GATEWAY",
"mVersion": "3.9.1",
"gaVersion": "3.9.1",
"agentVersion": "1.9.5",
"ExpirationDate": 32521996800000,
"ExpirationDate": 1665661007000,
"status": "DISCONNECTED",
"addresses": [{
"networkInterface": "engg"
},
{
"networkInterface": "engg"
}],
"clusterId": 768,
"clusterName": "gw-ext-2",
"serverPort": 987,
"currentClusteringPort": 987,
"runtimeInformation": {
"abcInfo": {
"runtime": {
"name": "abc",
"version": "1.2.3"
},
"specification": {
"vendor": "RRR",
"name": "RTR",
"version": "1.8.0"
}
},
"osInformation": {
"name": "LX",
"version": "4.78",
"architecture": "eng"
},
"ExpirationDate": 8765478999765
}
}],
"visibilityMap": {
"mapNodes": [{
"serverId": 765,
"visibleNodeIds": [765,
876],
"unknownNodeIps": []
},
{
"serverId": 876,
"visibleNodeIds": [765,
876],
"unknownNodeIps": []
}]
}
}]
So in each cluster we have two servers and this json continues to have around 15 clusters.
I want to filter out the status of each cluster and server in below format
name cluster/server status
gw-ext-1 CLUSTER RUNNING
gw-jpg208765-1 SERVER RUNNING
gw-jpg208765-2 SERVER DISCONNECTED
similarly for other clusters also.
I tried few things but its not giving me the servers .. it gives only cluster's details
target_id=echo \$targetIdResponse | ${env.WORKSPACE}/jq -r '.data[] | [.name, .type, .status]'
OR
target_id=echo \$targetIdResponse | ${env.WORKSPACE}/jq -r '.data[] | [.name, .type, .status, .servers.name, .servers.type, .servers.status]'
where $targetIdResponse contains my json data
I want to know how i can filter the above json to get the required data.
You need to have the header array the required fields in a separate array and put them together in a tabular format using #tsv
jq -r '[ "name", "cluster/server", "status" ],
( .data[] | [.name, .type, .status] ),
( .data[].servers[] | [ .name, .type, .status ] ) | #tsv'
The requirement was modified since originally posted to have the server information exactly below the cluster information
jq -r '[ "name", "cluster/server", "status" ],
( .data[] | [.name, .type, .status], ( .servers[] | [.name, .type, .status] ) ) | #tsv'

JSON Transformation using JQ

I am trying to transform my JSON to different structure using JQ. I am able to partially achieve my new structure, however i get a additional blocks of data.
As i iterate i am able to get the structure in new format. But additional structures are coming.
Code Snippet- https://jqplay.org/s/3gulSlZiWz
JSON
{
"amazon": {
"activeitem": 2,
"createdDate": "2019-01-15T17:36:31.588Z",
"lastModifiedDate": "2019-01-15T17:36:31.588Z",
"user": "net",
"userType": "new",
"items": [
{
"id": 1,
"name": "harry potter",
"state": "sold",
"type": {
"branded": false,
"description": "artwork",
"contentLevel": "season"
}
},
{
"id": 2,
"name": "adidas shoes",
"state": "in inventory",
"type": {
"branded": false,
"description": "Spprts",
"contentLevel": "season"
}
},
{
"id": 3,
"name": "watch",
"state": "returned",
"type": {
"branded": false,
"description": "walking",
"contentLevel": "special"
}
},
{
"id": 4,
"name": "adidas shoes",
"state": "in inventory",
"type": {
"branded": false,
"description": "running",
"contentLevel": "winter"
}
}
],
"product": {
"id": 4,
"name": "adidas shoes",
"source": "dealer",
"destination": "resident"
}
}
}
JQ Query:
.amazon|
{
userType: .userType,
userName: .user,
itemCatalog: {
itemId: .items[].id,
name: .items[].name
}
}
Expected Response:
{
"userType": "new",
"userName": "net",
"itemCatalog": {
"itemId": 1,
"name": "harry potter"
},{
"itemId": 2,
"name": "adidas shoes"
}, {
"itemId": 3,
"name": "watch"
},{
"itemId": 4,
"name": "adidas shoes"
}
}
But getting something weird long duplicated response.
As already pointed out in a comment, the "expected response" is not JSON and probably not what you want anyway. The following would make sense and in any case illustrates how to iterate appropriately:
.amazon
| { userType: .userType,
userName: .user,
itemCatalog: (.items | map({ itemId: .id, name} ))
}
Output
{
"userType": "new",
"userName": "net",
"itemCatalog": [
{
"itemId": 1,
"name": "harry potter"
},
{
"itemId": 2,
"name": "adidas shoes"
},
{
"itemId": 3,
"name": "watch"
},
{
"itemId": 4,
"name": "adidas shoes"
}
]
}

Convert json to include name and children values to feed D3

I am trying to get json converted from:
{
"Devices": [
{
"Udid": "7a2b0e6c928f2321a75e423ba23ae93d",
"SerialNumber": "RF1D232ZLEE",
"MacAddress": "40F232726FC8",
"Imei": "3576342323280150",
"EasId": "SEC1BC252327E92B",
"AssetNumber": "7a2b0e23223928f2321a75e423ba23ae93d",
"DeviceFriendlyName": "gel1 Android Android 5.0.1 ZLEE ",
"LocationGroupId": {
"Id": {
"Value": 19529
},
"Name": "Group Express"
},
"LocationGroupName": "Group Express",
"UserId": {
"Name": ""
},
"UserName": "",
"UserEmailAddress": "",
"Ownership": "S",
"PlatformId": {
"Id": {
"Value": 5
},
"Name": "Android"
},
"Platform": "Android",
"ModelId": {
"Id": {
"Value": 5
},
"Name": "samsung GT-I9505"
},
"Model": "samsung GT-I9505",
"OperatingSystem": "5.0.1",
"PhoneNumber": "+447881867010",
"LastSeen": "2016-07-06T14:01:03.590",
"EnrollmentStatus": "Unenrolled",
"ComplianceStatus": "NotAvailable",
"CompromisedStatus": false,
"LastEnrolledOn": "2016-06-15T16:01:38.763",
"LastComplianceCheckOn": "0001-01-01T00:00:00.000",
"LastCompromisedCheckOn": "2016-07-06T13:58:26.183",
"IsSupervised": false,
"DeviceMCC": {
"SIMMCC": "234",
"CurrentMCC": "234"
},
"AcLineStatus": 0,
"VirtualMemory": 0,
"Id": {
"Value": 23459
}
},
{
"Udid": "c5f94db71d406dae7f881d3edf059e",
"SerialNumber": "",
"MacAddress": "000C300F9108",
"Imei": "",
"EasId": "D80DB85EC411C8E9B28BC292A603F05C2C0EEEC8",
"AssetNumber": "c592f93db71d406dae7f881d3edf059e",
"DeviceFriendlyName": "user Windows 10 WinRT 10.0.10240 ",
"LocationGroupId": {
"Id": {
"Value": 18498
},
"Name": "Business Solutions"
},
"LocationGroupName": "Business Solutions",
"UserId": {
"Name": ""
},
"UserName": "",
"UserEmailAddress": "",
"Ownership": "C",
"PlatformId": {
"Id": {
"Value": 12
},
"Name": "WinRT"
},
"Platform": "WinRT",
"ModelId": {
"Id": {
"Value": 50
},
"Name": "Windows 10"
},
"Model": "Windows 10",
"OperatingSystem": "10.0.10240",
"PhoneNumber": "",
"LastSeen": "2016-05-03T10:54:07.650",
"EnrollmentStatus": "Unenrolled",
"ComplianceStatus": "NotAvailable",
"CompromisedStatus": false,
"LastEnrolledOn": "2016-01-29T16:41:57.760",
"LastComplianceCheckOn": "0001-01-01T00:00:00.000",
"LastCompromisedCheckOn": "0001-01-01T00:00:00.000",
"IsSupervised": false,
"DeviceMCC": {
"SIMMCC": "",
"CurrentMCC": ""
},
"AcLineStatus": 0,
"VirtualMemory": 0,
"Id": {
"Value": 23545
}
}
],
"Page": 0,
"PageSize": 500,
"Total": 13}
To something like:
{"name": "Devices",
"children": [
{"name":"Udid", "size":"7f0dsda63274692ea4f0b66fec67a020158"},
{"name":"SerialNumber", "size":"P988KJSPQF938"},
{"name":"MacAddress", "size":"1HJUSUD031C4"},
{"name":"Imei", "size":""},
{"name":"EasId", "size":"ApKJSPQF193"},
{"name":"AssetNumber", "size":"7f0cda636b3305fea4f0b66fec9997267a020158"},
{"name":"DeviceFriendlyName", "size":"TMcKenz iPad iOS 7.1.4 F193 "},
{"name":"LocationGroupId",
"children": [
{"name":"Id","size":7488},
{"name":"Name","size":"MCM"}
]
},
{"name":"UserId",
"children": [
{"name":"Id","size":6418},
{"name":"Name","size":"Tom McKenz"}
]
},
{"name":"UserName", "size":"TMcKenz"},
{"name":"UserEmailAddress", "size":"TMcKenz#awaw.com"}
]
}
Not sure what is the best practice here: is it possible to use D3.nest or do you need to iterate through all the nodes and change to 'name' and 'children' accordingly.