Given this data I am trying to return the servers
array with any matches from groups
array based on s_Group
value. However group_by(s_Group)
only returns those common to both arrays (with one extraneous non-match I cannot explain). It might be worth mentioning this is being done in a bash script so I am game to break the arrays into separate files and/or multiple steps if that makes things easier.
EDIT: I should have specified I want all the attributes from groups
pulled into the new servers
elements where a match occurs. Apologies for not making that clear. Adding a "desired output".
input data:
{
"servers": [
{
"location": "srv_apc1",
"f_Group": "auc-1"
},
{
"location": "srv_apc2",
"f_Group": "auc-1",
"c_Group": "c1"
},
{
"location": "srv_apc3",
"f_Group": "auc-1",
"c_Group": "c2"
},
{
"location": "srv_apc4",
"f_Group": "auc-1",
"c_Group": "c3"
},
{
"location": "srv_wc1",
"s_Group": "cb-1"
},
{
"location": "srv_wc2",
"s_Group": "cb-2"
},
{
"location": "srv_wc3",
"s_Group": "cb-3"
},
{
"location": "srv_wc4",
"s_Group": "cb-4"
}
],
"groups": [
{
"s_Group": "cb-1",
"options": [
"opt1",
"opt3",
"opt5",
"home"
]
},
{
"s_Group": "cb-2",
"options": [
"opt2",
"opt4",
"opt6",
"home"
]
},
{
"s_Group": "cb-3",
"options": [
"opt7",
"opt8",
"opt9",
"home",
"print"
]
},
{
"s_Group": "cb-4",
"options": [
"ems99",
"erec98",
"expr-77",
"home"
]
},
{
"s_Group": "extra-99",
"options": [
"conf1",
"ems34",
"erec1",
"home",
"chec99",
"franT"
]
}
]
}
jq:
.servers .groups | group_by(.s_Group) | map(add)
desired output:
{
"servers": [
[
{
"location": "srv_apc1",
"f_Group": "auc-1"
},
{
"location": "srv_apc2",
"f_Group": "auc-1",
"c_Group": "c1"
},
{
"location": "srv_apc3",
"f_Group": "auc-1",
"c_Group": "c2"
},
{
"location": "srv_apc4",
"f_Group": "auc-1",
"c_Group": "c3"
},
{
"location": "srv_wc1",
"s_Group": "cb-1",
"options": [
"opt1",
"opt3",
"opt5",
"home"
]
},
{
"location": "srv_wc2",
"s_Group": "cb-2",
"options": [
"opt2",
"opt4",
"opt6",
"home"
]
},
{
"location": "srv_wc3",
"s_Group": "cb-3",
"options": [
"opt7",
"opt8",
"opt9",
"home",
"print"
]
},
{
"location": "srv_wc4",
"s_Group": "cb-4",
"options": [
"ems99",
"erec98",
"expr-77",
"home"
]
}
]
]
}
CodePudding user response:
Everything can be done with one invocation of jq. If I understand the requirements correctly, you could use the following jq program:
INDEX(.groups[]; .s_Group) as $dict
| .servers
| map( . $dict[.f_Group // ""])
This returns the modified .servers array.
CodePudding user response:
Use JOIN
with an INDEX
on the .servers
items:
jq '{servers: [JOIN(
INDEX(.groups[]; .s_Group); .servers[]; .s_Group // empty; add
)]}'
{
"servers": [
{
"location": "srv_apc1",
"f_Group": "auc-1"
},
{
"location": "srv_apc2",
"f_Group": "auc-1",
"c_Group": "c1"
},
{
"location": "srv_apc3",
"f_Group": "auc-1",
"c_Group": "c2"
},
{
"location": "srv_apc4",
"f_Group": "auc-1",
"c_Group": "c3"
},
{
"location": "srv_wc1",
"s_Group": "cb-1",
"options": [
"opt1",
"opt3",
"opt5",
"home"
]
},
{
"location": "srv_wc2",
"s_Group": "cb-2",
"options": [
"opt2",
"opt4",
"opt6",
"home"
]
},
{
"location": "srv_wc3",
"s_Group": "cb-3",
"options": [
"opt7",
"opt8",
"opt9",
"home",
"print"
]
},
{
"location": "srv_wc4",
"s_Group": "cb-4",
"options": [
"emsar",
"ereceipt",
"expressmtreceive",
"home",
"mtagentlookup",
"mtreceive",
"mtstatus"
]
}
]
}