How to extract this string with JQ - json

I have a JSON file like this :
{
"filter": [
{
"id": "id_1",
"criteria": {
"from": "mail1#mail.com"
},
"action": {
"addLabelIds": [
"Label_1"
],
"removeLabelIds": [
"IMPORTANT",
"SPAM"
]
}
},
{
"id": "id_2",
"criteria": {
"from": "mail2#mail.com"
},
"action": {
"addLabelIds": [
"Label_2"
],
"removeLabelIds": [
"IMPORTANT",
"SPAM"
]
}
}
]
}
I would like to extract id value only where from = mail2#mail.com
I have tried this but does not work :
jq '.filter[] | select(.criteria.from | test("mail2#mail.com"; "i")) | .id'
Have you got any idea?
Thanks
L.

thanks to #Charles Duffy
solution:
select(.criteria.from == "mail2#mail.com")

Related

JQ: group by into single object with groups as keys

I have the following data:
[
{
"company.u_ats_region": "Region1",
"hostname": "host1",
"install_status": "1",
"os": "Windows",
"os_domain": "test.com"
},
{
"company.u_ats_region": "Region2",
"hostname": "host2",
"install_status": "1",
"os": "Windows",
"os_domain": "test.com"
},
{
"company.u_ats_region": "Region3",
"hostname": "host3",
"install_status": "7",
"os": "Windows",
"os_domain": "test.com"
}
]
And I've been using this query
{count: length,
regions: [group_by(."company.u_ats_region")[] |
{( [0]."company.u_ats_region"): [.[] |
{name: (.hostname+"."+.os_domain),
os: .os}]}]}
to convert the data into the following:
{
"count": 3,
"regions": [
{
"Region1": [
{
"name": "host1.test.com",
"os": "Windows"
}
]
},
{
"Region2": [
{
"name": "host2.test.com",
"os": "Windows"
}
]
},
{
"Region3": [
{
"name": "host3.test.com",
"os": "Windows"
}
]
}
]
}
This is close to what I'm trying to achieve but I would like 'regions' to be a single object with each region being a key within that object like this:
{
"count": 3,
"regions": {
"Region1": [
{
"name": "host1.test.com",
"os": "Windows"
}
],
"Region2": [
{
"name": "host2.test.com",
"os": "Windows"
}
],
"Region3": [
{
"name": "host3.test.com",
"os": "Windows"
}
]
}
}
I have tried playing around with 'add' but that still didn't bring me any closer to the result I'm trying to achieve. Any help is appreciated!
Creating an object with key and value fields, then using from_entries would be one way:
{
count: length,
regions: group_by(."company.u_ats_region")
| map({
key: .[0]."company.u_ats_region",
value: map({name: "\(.hostname).\(.os_domain)", os})
})
| from_entries
}
{
"count": 3,
"regions": {
"Region1": [
{
"name": "host1.test.com",
"os": "Windows"
}
],
"Region2": [
{
"name": "host2.test.com",
"os": "Windows"
}
],
"Region3": [
{
"name": "host3.test.com",
"os": "Windows"
}
]
}
}
Demo
You can define a custom function which performs the grouping and then tranfsorm the result. Using a function avoids having to repeat the selector:
def group_to_obj(f):
group_by(f) | map({key:first|f, value:.}) | from_entries;
{
count: length,
regions: group_to_obj(."company.u_ats_region")
| map_values(map({name: "\(.hostname).\(.os_domain)", os}))
}
Output:
{
"count": 3,
"regions": {
"Region1": [
{
"name": "host1.test.com",
"os": "Windows"
}
],
"Region2": [
{
"name": "host2.test.com",
"os": "Windows"
}
],
"Region3": [
{
"name": "host3.test.com",
"os": "Windows"
}
]
}
}
Using reduce to iteratively build up the arrays would be another way:
{
count: length,
regions: (
reduce .[] as $i ({};
.[$i."company.u_ats_region"] += [$i | {name: "\(.hostname).\(.os_domain)", os}]
)
)
}
{
"count": 3,
"regions": {
"Region1": [
{
"name": "host1.test.com",
"os": "Windows"
}
],
"Region2": [
{
"name": "host2.test.com",
"os": "Windows"
}
],
"Region3": [
{
"name": "host3.test.com",
"os": "Windows"
}
]
}
}
Demo

need to extract specific string with JQ

I have a JSON file (see below) and with JQ I need to extract the resourceName value for value = mail#mail1.com
So in my case, the result should be name_1
Any idea to do that ?
Because this does not work :
jq '.connections[] | select(.emailAddresses.value | test("mail#mail1.com"; "i")) | .resourceName' file.json
{
"connections": [
{
"resourceName": "name_1",
"etag": "123456789",
"emailAddresses": [
{
"metadata": {
"primary": true,
"source": {
"type": "CONTACT",
"id": "123456"
}
},
"value": "mail#mail1.com",
}
]
},
{
"resourceName": "name_2",
"etag": "987654321",
"emailAddresses": [
{
"metadata": {
"primary": true,
"source": {
"type": "CONTACT",
"id": "654321"
},
"sourcePrimary": true
},
"value": "mail#mail2.com"
}
]
}
],
"totalPeople": 187,
"totalItems": 187
}
One solution is to store the parent object while selecting on the child array:
jq '.connections[] | . as $parent | .emailAddresses // empty | .[] | select(.value == "mail#mail1.com") | $parent.resourceName' file.json
emailAddresses is an array. Use any if finding one element that matches will suffice.
.connections[] | select(any(.emailAddresses[];.value == "mail#mail1.com")).resourceName

Re-organize json using jq

I want to re-organize a json using jq.
My json is like:
[
{
"id": "id1",
"name": "Robin"
},
{
"id": "id2",
"name": "John"
},
{
"id": "id3",
"name": "Jane"
}
]
I want to have an output as :
[
{
"Robin": "id1"
},
{
"John": "id2"
},
{
"Jane": "id3"
}
]
How to achieve this?
Thanks in advance
Yu need:
cat data1.jtxt | jq 'to_entries|map({(.value.name):(.value.id)})'
My output:
[
{
"Robin": "id1"
},
{
"John": "id2"
},
{
"Jane": "id3"
}
]
I cannot understand how was this command so difficult to find
[.[] | {(.id):.name}] | add
gives you:
{
"id1": "Robin",
"id2": "John",
"id3": "Jane"
}
If you want to keep the "object separation" just remove the | add
This question somehow led me to it.

Extract from json with | jq by a given word

Can somebody help me to extract with | jq the following:
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"pod": "dev-cds-5c97cf7f78-sw6b9"
},
"values": [
[
1588204800,
"0.3561394483796914"
],
[
1588215600,
"0.3607968456046861"
],
[
1588226400,
"0.3813882532417868"
],
[
1588237200,
"0.6264355815408573"
]
]
},
{
"metric": {
"pod": "uat-cds-66ccc9685-b5tvh"
},
"values": [
[
1588204800,
"0.9969746974696218"
],
[
1588215600,
"0.7400881057270005"
],
[
1588226400,
"1.2298959318837195"
],
[
1588237200,
"0.9482296838254507"
]
]
}
]
}
}
I need to obtain all-values individually by given word dev-cds and not all the name dev-cds-5c97cf7f78-sw6b9.
Result desired:
{
"metric": {
"pod": "dev-cds-5c97cf7f78-sw6b9"
},
"values": [
[
1588204800,
"0.3561394483796914"
],
[
1588215600,
"0.3607968456046861"
],
[
1588226400,
"0.3813882532417868"
],
[
1588237200,
"0.6264355815408573"
]
]
}
You should first iterate over the result array. Check if the pod inside, metric object has the value that contains "dev-cds".
.data.result[] | if .metric.pod | contains("dev-cds") then . else empty end
https://jqplay.org/s/54OH83qHKP

jq sort using the value of a nested array element

I need some help using jq to sort an array of elements where each element contains a nested
tags array of elements. My input JSON looks like this:
{
"result": [
{
"name": "ct-1",
"tags": [
{
"key": "service_name",
"value": "BaseCT"
},
{
"key": "sequence",
"value": "bb"
}
]
},
{
"name": "ct-2",
"tags": [
{
"key": "service_name",
"value": "BaseCT"
},
{
"key": "sequence",
"value": "aa"
}
]
}
]
}
I would like to sort using the value of the sequence tag in the nested tags array so that the output looks like this:
{
"result": [
{
"name": "ct-2",
"tags": [
{
"key": "service_name",
"value": "BaseCT"
},
{
"key": "sequence",
"value": "aa"
}
]
},
{
"name": "ct-1",
"tags": [
{
"key": "service_name",
"value": "BaseCT"
},
{
"key": "sequence",
"value": "bb"
}
]
}
]
}
I have tried the following jq command:
$ jq '.result |= ([.[] | .tags[] | select(.key == "sequence") | .value] | sort_by(.))' input.json
but I get the following result:
{
"result": [
"aa",
"bb"
]
}
Please let me know if you know how to deal with this scenario.
from_entries converts an array of key-value pairs to an object, you can use it with sort_by like this:
.result |= sort_by(.tags | from_entries | .sequence)