transform only subarray of objects in JQ - json

I am trying to transform this JSON object:
{
"id_1": {},
"id_2": {
"sys": "S",
"details": [
{
"detail": "S1",
"index": 0
},
{
"detail": " ",
"index": 1
},
{
"detail": " ",
"index": 2
},
{
"detail": " ",
"index": 3
},
{
"detail": " ",
"index": 4
}
],
"color": "Grey"
},
"id_3": {
"sys": "A",
"details": [
{
"detail": "240",
"index": 0
},
{
"detail": "63",
"index": 1
},
{
"detail": "70",
"index": 2
},
{
"detail": " ",
"index": 3
},
{
"detail": " ",
"index": 4
}
],
"color": "White"
},
"id_4": {},
"id_5": {
"sys": "G",
"details": [
{
"detail": "266",
"index": 0
},
{
"detail": "G",
"index": 1
},
{
"detail": "1",
"index": 2
},
{
"detail": " ",
"index": 3
},
{
"detail": " ",
"index": 4
}
],
"color": "Red"
}
}
into that one:
{
"id_1": {},
"id_2": {
"sys": "S",
"details": ["S1"],
"color": "Grey",
},
"id_3": {
"sys": "A",
"details": ["240","63","70"],
"color": "White",
},
"id_4": {},
"id_5": {
"sys": "G",
"details": ["266", "G", "1"],
"color": "Red",
}
}
There are also empty objects in the outer object that should be remained. Only the key details should be transformed, others should be kept.
Could not achive to create any valid query with map nor with select. The only valid jq I have created so far: .[]? | [.details[]? | select(.detail != " ")] | .[] .detail, but only results the details strings...

Here is one way:
map_values(
select(has("details")) .details |=
map(.detail | select(. != " "))
)
Online demo

You can also use values to empty objects not having a .details field (or having one with null as its value).
.[].details |= (values | map(.detail | select(. != " ")))
{
"id_1": {},
"id_2": {
"sys": "S",
"details": ["S1"],
"color": "Grey"
},
"id_3": {
"sys": "A",
"details": ["240", "63", "70"],
"color": "White"
},
"id_4": {},
"id_5": {
"sys": "G",
"details": ["266", "G", "1"],
"color": "Red"
}
}
Demo

Try this :
jq 'map_values(.details? |= map(select(.detail != " "))' file.json

Related

Cannot get jq to query json object [duplicate]

This question already has answers here:
How to use jq when the variable has reserved characters?
(3 answers)
Closed 6 months ago.
I have a JSON file that I am trying to query with jq. I am unable to retrieve the observations. I am trying to retieve each of the "observations using the following command and not able to get to the result:
cat sample3.json | jq .dataSets[0].series.0:0:0:0:0.observations.0[0]
I am able to retieve up to the series using:
cat sample3.json | jq .dataSets[0].series
But once I try to drill down further I am getting a compile error:
$ cat sample3.json | jq .dataSets[0].series.0:0:0:0:0
jq: error: syntax error, unexpected LITERAL, expecting end of file (Unix shell quoting issues?) at <top-level>, line 1:
.dataSets[0].series.0:0:0:0:0
jq: 1 compile error
I am not sure what I am doing wrong here....
The input file is:
{
"header": {
"id": "b8be2cd5-33bf-4687-9e81-eb032f6f8a71",
"test": false,
"prepared": "2022-09-01T13:30:57.013+02:00",
"sender": {
"id": "ECB"
}
},
"dataSets": [
{
"action": "Replace",
"validFrom": "2022-09-01T13:30:57.013+02:00",
"series": {
"0:0:0:0:0": {
"attributes": [
0,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
null,
0,
null,
0,
0,
0,
0
],
"observations": {
"0": [
1.4529,
0,
0,
null,
null
],
"1": [
1.4472,
0,
0,
null,
null
],
"2": [
1.4591,
0,
0,
null,
null
]
}
}
}
}
],
"structure": {
"links": [
{
"title": "Exchange Rates",
"rel": "dataflow",
"href": "https://sdw-wsrest.ecb.europa.eu:443/service/dataflow/ECB/EXR/1.0"
}
],
"name": "Exchange Rates",
"dimensions": {
"series": [
{
"id": "FREQ",
"name": "Frequency",
"values": [
{
"id": "D",
"name": "Daily"
}
]
},
{
"id": "CURRENCY",
"name": "Currency",
"values": [
{
"id": "AUD",
"name": "Australian dollar"
}
]
},
{
"id": "CURRENCY_DENOM",
"name": "Currency denominator",
"values": [
{
"id": "EUR",
"name": "Euro"
}
]
},
{
"id": "EXR_TYPE",
"name": "Exchange rate type",
"values": [
{
"id": "SP00",
"name": "Spot"
}
]
},
{
"id": "EXR_SUFFIX",
"name": "Series variation - EXR context",
"values": [
{
"id": "A",
"name": "Average"
}
]
}
],
"observation": [
{
"id": "TIME_PERIOD",
"name": "Time period or range",
"role": "time",
"values": [
{
"id": "2022-08-29",
"name": "2022-08-29",
"start": "2022-08-29T00:00:00.000+02:00",
"end": "2022-08-29T23:59:59.999+02:00"
},
{
"id": "2022-08-30",
"name": "2022-08-30",
"start": "2022-08-30T00:00:00.000+02:00",
"end": "2022-08-30T23:59:59.999+02:00"
},
{
"id": "2022-08-31",
"name": "2022-08-31",
"start": "2022-08-31T00:00:00.000+02:00",
"end": "2022-08-31T23:59:59.999+02:00"
}
]
}
]
},
"attributes": {
"series": [
{
"id": "TIME_FORMAT",
"name": "Time format code",
"values": [
{
"name": "P1D"
}
]
},
{
"id": "BREAKS",
"name": "Breaks",
"values": []
},
{
"id": "COLLECTION",
"name": "Collection indicator",
"values": [
{
"id": "A",
"name": "Average of observations through period"
}
]
},
{
"id": "COMPILING_ORG",
"name": "Compiling organisation",
"values": []
},
{
"id": "DISS_ORG",
"name": "Data dissemination organisation",
"values": []
},
{
"id": "DOM_SER_IDS",
"name": "Domestic series ids",
"values": []
},
{
"id": "PUBL_ECB",
"name": "Source publication (ECB only)",
"values": []
},
{
"id": "PUBL_MU",
"name": "Source publication (Euro area only)",
"values": []
},
{
"id": "PUBL_PUBLIC",
"name": "Source publication (public)",
"values": []
},
{
"id": "UNIT_INDEX_BASE",
"name": "Unit index base",
"values": []
},
{
"id": "COMPILATION",
"name": "Compilation",
"values": []
},
{
"id": "COVERAGE",
"name": "Coverage",
"values": []
},
{
"id": "DECIMALS",
"name": "Decimals",
"values": [
{
"id": "4",
"name": "Four"
}
]
},
{
"id": "NAT_TITLE",
"name": "National language title",
"values": []
},
{
"id": "SOURCE_AGENCY",
"name": "Source agency",
"values": [
{
"id": "4F0",
"name": "European Central Bank (ECB)"
}
]
},
{
"id": "SOURCE_PUB",
"name": "Publication source",
"values": []
},
{
"id": "TITLE",
"name": "Title",
"values": [
{
"name": "Australian dollar/Euro"
}
]
},
{
"id": "TITLE_COMPL",
"name": "Title complement",
"values": [
{
"name": "ECB reference exchange rate, Australian dollar/Euro, 2:15 pm (C.E.T.)"
}
]
},
{
"id": "UNIT",
"name": "Unit",
"values": [
{
"id": "AUD",
"name": "Australian dollar"
}
]
},
{
"id": "UNIT_MULT",
"name": "Unit multiplier",
"values": [
{
"id": "0",
"name": "Units"
}
]
}
],
"observation": [
{
"id": "OBS_STATUS",
"name": "Observation status",
"values": [
{
"id": "A",
"name": "Normal value"
}
]
},
{
"id": "OBS_CONF",
"name": "Observation confidentiality",
"values": [
{
"id": "F",
"name": "Free"
}
]
},
{
"id": "OBS_PRE_BREAK",
"name": "Pre-break observation value",
"values": []
},
{
"id": "OBS_COM",
"name": "Observation comment",
"values": []
}
]
}
}
}
The .foo syntax cannot be used if the key name has anything but alphanumeric characters or the underscore, or if the first character of the key name is numeric.
Assuming you are using a recent version of jq,
you can always use the form: ."foo", which is actually an abbreviation of the basic form, .["foo"].
So assuming you're using a sufficiently recent version of jq, your query could begin with:
.dataSets[0].series."0:0:0:0:0"
If you are presenting the jq query on a command line, then you may have to escape the double-quotes appropriately, e.g. in a bash shell, by enclosing the jq query in single-quotes.

JQ - unique count of each value in an array

I'm needing to solve this with JQ. I have a large lists of arrays in my json file and am needing to do some sort | uniq -c types of stuff on them. Specifically I have a relatively nasty looking fruit array that needs to break down what is inside. I'm aware of unique and things like that, and imagine there is likely a simple way to do this, but I've been trying run down assigning things as variables and appending and whatnot, but I can't get the most basic part of counting the unique values per that fruit array, and especially not without breaking the rest of the content (hence the variable ideas). Please tell me I'm overthinking this.
I'd like to turn this;
[
{
"uid": "123abc",
"tID": [
"T19"
],
"fruit": [
"Kiwi",
"Apple",
"",
"",
"",
"Kiwi",
"",
"Kiwi",
"",
"",
"Mango",
"Kiwi"
]
},
{
"uid": "456xyz",
"tID": [
"T15"
],
"fruit": [
"",
"Orange"
]
}
]
Into this;
[
{
"uid": "123abc",
"tID": [
"T19"
],
"metadata": [
{
"name": "fruit",
"value": "Kiwi - 3"
},
{
"name": "fruit",
"value": "Mango - 1"
},
{
"name": "fruit",
"value": "Apple - 1"
}
]
},
{
"uid": "456xyz",
"tID": [
"T15"
],
"metadata": [
{
"name": "fruit",
"value": "Orange - 1"
}
]
}
]
Using group_by and length would be one way:
jq '
map(with_entries(select(.key == "fruit") |= (
.value |= (group_by(.) | map(
{name: "fruit", value: "\(.[0] | select(. != "")) - \(length)"}
))
| .key = "metadata"
)))
'
[
{
"uid": "123abc",
"tID": [
"T19"
],
"metadata": [
{
"name": "fruit",
"value": "Apple - 1"
},
{
"name": "fruit",
"value": "Kiwi - 4"
},
{
"name": "fruit",
"value": "Mango - 1"
}
]
},
{
"uid": "456xyz",
"tID": [
"T15"
],
"metadata": [
{
"name": "fruit",
"value": "Orange - 1"
}
]
}
]
Demo

extract collection from json based on a condition using logic app

I am trying to Extract and sum a particular value using group by from json collection in azure logic app. Trying to achieve this by applying "Condition" connector. My Json file looks like below:
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1",
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1",
},
]
}
]
I want to calculate the sum of Qty group by I_Id from array Res using logic app connector "Condition".
Note: As Res is an array, there can be repetition I_Id with same value, hence, the requirement to get the Qty count based on I_Id
There are few ways to achieve your requirement but here is one of the workaround that worked when reproduced from our end.
Firstly, I have initialised a temporary integer variable to iterated inside the "Res" Array using Until Loop by checking the length of "Res" using the below expression.
length(body('Parse_JSON')?['Release']?[0]?['Res'])
Inside Until I have used condition action to check if I_Id is same using the below expression to the left.
body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['I_Id']
and below expression to the right
body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['I_Id']
Then if the condition satisfies I'm adding the Qty using the expression as below.
add(body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['Qty'],body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['Qty'])
Here is the flow of my logic app
[Optional step]
Considering the bigger picture, I have initialzed another variable quantity and added the resultant of Compose 4 to Qty variable
RESULTS:
Considering the below sample JSON
{
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 5,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
}
]
}
]
}
Here is the result
To avoid confusion try the below code view in your resource
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 5,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
}
]
}
]
},
"runAfter": {},
"type": "Compose"
},
"Compose_3": {
"inputs": "#variables('Qty')",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "temp",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "Qty",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"Release": {
"items": {
"properties": {
"O_Id": {
"type": "string"
},
"R_ID": {
"type": "string"
},
"Res": {
"items": {
"properties": {
"A_Id": {
"type": "string"
},
"F_Qty": {
"type": "integer"
},
"I_Id": {
"type": "string"
},
"OL_Id": {
"type": "string"
},
"Qty": {
"type": "integer"
},
"RL_Id": {
"type": "string"
},
"Unique_Identifier": {
"type": "string"
}
},
"required": [
"A_Id",
"F_Qty",
"I_Id",
"OL_Id",
"Qty",
"RL_Id",
"Unique_Identifier"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"O_Id",
"R_ID",
"Res"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Until": {
"actions": {
"Condition": {
"actions": {
"Compose_2": {
"inputs": "#add(outputs('Compose_4'),variables('Qty'))",
"runAfter": {
"Compose_4": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_4": {
"inputs": "#add(body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['Qty'],body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['Qty'])",
"runAfter": {},
"type": "Compose"
},
"Set_variable": {
"inputs": {
"name": "Qty",
"value": "#outputs('Compose_2')"
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"expression": {
"and": [
{
"equals": [
"#body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['I_Id']",
"#body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['I_Id']"
]
}
]
},
"runAfter": {},
"type": "If"
},
"Increment_variable": {
"inputs": {
"name": "temp",
"value": 1
},
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('temp'), length(body('Parse_JSON')?['Release']?[0]?['Res']))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}

Kubernetes + jq - retrieving containers list per pod yields cartesian product

Im trying to use jq on kubernetes json output, to create new json object containing list of objects - container and image per pod, however im getting cartesian product.
my input data (truncated from sensitive info):
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2021-06-30T12:45:40Z",
"name": "pod-1",
"namespace": "default",
"resourceVersion": "757679286",
"selfLink": "/api/v1/namespaces/default/pods/pod-1"
},
"spec": {
"containers": [
{
"image": "image-1",
"imagePullPolicy": "Always",
"name": "container-1",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"readOnly": true
}
]
},
{
"image": "image-2",
"imagePullPolicy": "Always",
"name": "container-2",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
"enableServiceLinks": true,
"priority": 0,
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "default",
"serviceAccountName": "default",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [
{
"name": "default-token-b954f",
"secret": {
"defaultMode": 420,
"secretName": "default-token-b954f"
}
}
]
},
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"message": "containers with unready status: [container-1 container-2]",
"reason": "ContainersNotReady",
"status": "False",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"message": "containers with unready status: [container-1 container-2]",
"reason": "ContainersNotReady",
"status": "False",
"type": "ContainersReady"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"image": "image-1",
"imageID": "",
"lastState": {},
"name": "container-1",
"ready": false,
"restartCount": 0,
"started": false,
"state": {
"waiting": {
"message": "Back-off pulling image \"image-1\"",
"reason": "ImagePullBackOff"
}
}
},
{
"image": "image-2",
"imageID": "",
"lastState": {},
"name": "container-2",
"ready": false,
"restartCount": 0,
"started": false,
"state": {
"waiting": {
"message": "Back-off pulling image \"image-2\"",
"reason": "ImagePullBackOff"
}
}
}
],
"qosClass": "BestEffort",
"startTime": "2021-06-30T12:45:40Z"
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": "",
"selfLink": ""
}
}
my command:
jq '.items[] | { "name": .metadata.name, "containers": [{ "name": .spec.containers[].name, "image": .spec.containers[].image }]} '
desired output:
{
"name": "pod_1",
"containers": [
{
"name": "container_1",
"image": "image_1"
},
{
"name": "container_2",
"image": "image_2"
}
]
}
output I get:
{
"name": "pod-1",
"containers": [
{
"name": "container-1",
"image": "image-1"
},
{
"name": "container-1",
"image": "image-2"
},
{
"name": "container-2",
"image": "image-1"
},
{
"name": "container-2",
"image": "image-2"
}
]
}
Could anyone explain what am I doing wrong?
Best Regards, Piotr.
The problem is "name": .spec.containers[].name and "image": .spec.containers[].image:
Both expressions generate a sequence of each value for name and image which will than be combined.
Simplified example of why you get a Cartesian product:
jq -c -n '{name: ("A", "B"), value: ("C", "D")}'
outputs:
{"name":"A","value":"C"}
{"name":"A","value":"D"}
{"name":"B","value":"C"}
{"name":"B","value":"D"}
You get the desired output using this jq filter on your input:
jq '
.items[]
| {
"name": .metadata.name,
"containers": .spec.containers
| map({name, image})
}'
output:
{
"name": "pod-1",
"containers": [
{
"name": "container-1",
"image": "image-1"
},
{
"name": "container-2",
"image": "image-2"
}
]
}

json - query with conditions

I have following json:
{
"id": "1",
"name": "profile1",
"userId": "0",
"groupId": "3",
"attributes": [
{
"id": "104",
"name": "Enable",
"value": "1"
},
{
"id": "105",
"name": "TargetNode",
"value": "system1"
},
{
"id": "106",
"name": "Timeout",
"value": "30"
}
],
"xconns": [
{
"id": "1",
"locked": false,
"attributeList": [
{
"id": "101",
"name": "Lgrp",
"value": "1"
},
{
"id": "102",
"name": "IsRem",
"value": "1"
},
{
"id": "103",
"name": "Media",
"value": "1"
}
]
},
{
"id": "1",
"locked": false,
"attributeList": [
{
"id": "101",
"name": "Lgrp",
"value": "1"
},
{
"id": "102",
"name": "IsRem",
"value": "1"
},
{
"id": "103",
"name": "Media",
"value": "1"
}
]
},
{
"id": "1",
"locked": false,
"attributeList": [
{
"id": "101",
"name": "Lgrp",
"value": "1"
},
{
"id": "102",
"name": "IsRem",
"value": "1"
},
{
"id": "103",
"name": "Media",
"value": "1"
}
]
}
]
}
{
"id": "2",
"name": "profile2",
"userId": "7",
"groupId": "0",
"attributes": [
{
"id": "104",
"name": "Enable",
"value": "1"
},
{
"id": "105",
"name": "TargetNode",
"value": "system2"
},
{
"id": "106",
"name": "Timeout",
"value": "30"
}
],
"xconns": [
{
"id": "2",
"locked": false,
"attributeList": [
{
"id": "101",
"name": "Lgrp",
"value": "1"
},
{
"id": "102",
"name": "IsRem",
"value": "1"
},
{
"id": "103",
"name": "Media",
"value": "1"
}
]
},
{
"id": "2",
"locked": false,
"attributeList": [
{
"id": "101",
"name": "Lgrp",
"value": "1"
},
{
"id": "102",
"name": "IsRem",
"value": "1"
},
{
"id": "103",
"name": "Media",
"value": "1"
}
]
},
{
"id": "2",
"locked": false,
"attributeList": [
{
"id": "101",
"name": "Lgrp",
"value": "1"
},
{
"id": "102",
"name": "IsRem",
"value": "1"
},
{
"id": "103",
"name": "Media",
"value": "1"
}
]
}
]
}
I can filter following:
$ jq -r 'select([.attributes[] | .name == "TargetNode" ] | any ) | [{userId, groupId, id, name}] | .[] | if (.userId == "0") then del(.userId) else . end | if (.groupId == "0") then del(.groupId) else . end | to_entries | map("\(.key | ascii_upcase):\(.value)") | #tsv' file.json
GROUPID:3 ID:1 NAME:profile1
USERID:7 ID:2 NAME:profile2
I need to add also value of TargetNode:
GROUPID:3 ID:1 NAME:profile1 TARGETNODE:system1
USERID:7 ID:2 NAME:profile2 TARGETNODE:system2
is there a way to include it in
[{userId, groupId, id, name, TargetNode}]
to get the value of TargetNode and not null?
GROUPID:3 ID:1 NAME:profile1 TARGETNODE:null
USERID:7 ID:2 NAME:profile2 TARGETNODE:null
Update:
the solution provided by RomanPerekhrest is nearly ok, but there is one issue because the json file in real is much bigger, there are more attrobutes in "main secttion", for example:
{
"id": "1",
"name": "profile1",
"userId": "0",
"groupId": "3",
"attrib101": "A",
"attrib102": "B",
"attributes": [
...
...
it is cousing that RomanPerekhrest's jq filter returns too much...
how to rid of them too?
ID:1 NAME:profile1 GROUPID:3 ATTRIB101:A ATTRIB102:B TARGETNODE:system1
ID:2 NAME:profile2 USERID:7 ATTRIB101:C ATTRIB102:D TARGETNODE:system2
jq solution:
jq -r '.attributes |= map(select(.name == "TargetNode"))
| if (.attributes | length != 0) then .targetNode = .attributes[0].value else . end
| if (.userId == "0") then del(.userId) else . end
| if (.groupId == "0") then del(.groupId) else . end
| del(.attributes, .xconns) | to_entries
| map("\(.key | ascii_upcase):\(.value)") | #tsv' file.json
If an object with "name": "TargetNode" pair not exists - TARGETNODE won't be added into resulting structure
The output:
ID:1 NAME:profile1 GROUPID:3 TARGETNODE:system1
ID:2 NAME:profile2 USERID:7 TARGETNODE:system2