I'm using Ansible to call the same administration API on two different servers and then selecting the core details of the applications from the responses using jq.
According to Ansible type_debug the registered variables are of type dict
ok: [localhost] => {
"node1_applications | type_debug": "dict"
}
ok: [localhost] => {
"node2_applications | type_debug": "dict"
}
The JSON from the two responses looks like
{
"Node": "ESB1",
"AppCoreDetails": [
{
"ApplicationName": "APP_Config_V1",
"LastModified": "2023-08-25 12:23:26"
},
{
"ApplicationName": "APP_Intervals_V1",
"LastModified": "2022-11-23 14:46:58"
}
]
}
{
"Node": "ESB2",
"AppCoreDetails": [
{
"ApplicationName": "APP_Config_V1",
"LastModified": "2023-08-25 12:03:30"
},
{
"ApplicationName": "APP_Intervals_V1",
"LastModified": "2022-11-23 14:46:58"
}
]
}
Where the LastModified date of the first entry in AppCoreDetails is different and for the second entry it's the same.
I'd like to get the set of objects where the LastMofified dates are different.
{
"AppCoreDetails": [
{
"ApplicationName": "APP_Config_V1",
"LastModified": "2023-08-25 12:23:26"
}
]
}
BTW I found and tried experimenting with this but failed to convert from simple fields to objects enter link description here
As you've tagged jq, this assumes you want to call jq with the two JSON responses as its input.
You can read in both objects into an array using the --slurp
(or -s
) flag, and reduce them to the relevant values. Then, use transpose
to align the items, and filter for differences using select
.
jq -s '
map(.AppCoreDetails) | transpose
| {AppCoreDetails: map(select(first != last)[0])}
'
This assumes that the .ApplicationName
values are already aligned for both cases, i.e. the arrays have the same number of items and the names come in the same order. If this is not necessarily the case, specify how to deal with dangling matches. Here's an approach using JOIN
and INDEX
to find matching .ApplicationName
values:
jq -s 'map(.AppCoreDetails) | {AppCoreDetails: [JOIN(
INDEX(last[]; .ApplicationName); first[]; .ApplicationName; select(first != last)[0]
)]}'
Given the two sample inputs, both approaches output
{
"AppCoreDetails": [
{
"ApplicationName": "APP_Config_V1",
"LastModified": "2023-08-25 12:23:26"
}
]
}