I have a 26MB JSON file containing UN/LOCODE data that I want to restructure and remove some data from so that it takes less space in my app’s binary package.
The JSON contains an array of objects like this:
{
"Change": null,
"Coordinates": "4234N 00135E",
"Country": "AD",
"Date": "0307",
"Function": "--3-----",
"IATA": null,
"Location": "CAN",
"Name": "Canillo",
"NameWoDiacritics": "Canillo",
"Remarks": null,
"Status": "RL",
"Subdivision": null
}
The desired structure is an object rather than an array, keyed on the concatenation of the Country and Location fields, but the only nested fields that I am interested in are "Name" and "Coordinates".
I have been able to accomplish the first step with:
jq 'INDEX("\(.Country)-\(.Location)")'
giving me:
{
"AD-CAN": {
"Change": null,
"Coordinates": "4234N 00135E",
"Country": "AD",
"Date": "0307",
"Function": "--3-----",
"IATA": null,
"Location": "CAN",
"Name": "Canillo",
"NameWoDiacritics": "Canillo",
"Remarks": null,
"Status": "RL",
"Subdivision": null
},
...
}
but I cannot figure out how to get only the desired keys from the nested objects inside the new top-level object.
If this can’t be done with jq I’ll have to resort to a custom script to do it.
>Solution :
Just reshape the objects using map_values:
jq 'INDEX("\(.Country)-\(.Location)") | map_values({Name, Coordinates})'
Or do it all in one go using reduce:
jq 'reduce .[] as $i ({}; ."\($i.Country)-\($i.Location)" = ($i|{Name, Coordinates}))'