I'm trying to save some values from a bash-array into an existing json. I tried some different approaches, but I didn't manage to solve the issue. What am I missing here?
input.json
{
"type": "FeatureCollection",
"name": "test",
"features": [
{ "type": "Feature", "properties": { "OBJECTID": 3213, "USE": "dem", "tile": "4045644"}},
{ "type": "Feature", "properties": { "OBJECTID": 3214, "USE": "dem", "tile": "4045646"}},
{ "type": "Feature", "properties": { "OBJECTID": 3215, "USE": "dem", "tile": "4045648"}}
]
}
Output of some calculations in Bash - 100% derived from input.json. So this array length == length of the "features[]"-array in the input.json
printf '%s\n' "${pushintojson[@]}"
4045646 NV NV NV
4045648 NV 4045644 NV
4045650 NV 4045646 NV
jq '.features |= map(.properties = {NOSW: $ARGS.positional})' --args "${pushintojson[@]}" <<< "${input.json}"
So this produces this (newlines added by me for readability):
{
"type":"FeatureCollection",
"name":"test",
"features": [
{"type":"Feature","properties":{"OBJECTID":3213,"USE":"dem","tile":"4045644",
"NOSW":[
"4045646 NV NV NV",
"4045648 NV 4045644 NV",
"4045650 NV 4045646 NV"
]}},
{"type":"Feature","properties":{"OBJECTID":3214,"USE":"dem","tile":"4045646",
"NOSW":[
"4045646 NV NV NV",
"4045648 NV 4045644 NV",
"4045650 NV 4045646 NV"
]}},
{"type":"Feature","properties":{"OBJECTID":3215,"USE":"dem","tile":"4045648",
"NOSW":[
"4045646 NV NV NV",
"4045648 NV 4045644 NV",
"4045650 NV 4045646 NV"
]}}
]
}
All values of the bash-array are saved to EVERY element. It's supposed to be just one value per json-object - actually as an array itself. So in pseudo: "pushintojson[0]" needs to be under "features[0]", pushintojson[1]" to "features[1]" pushintojson[2]" to "features[2]" etc.
DESIRED OUTPUT
{
"type":"FeatureCollection",
"name":"test",
"features": [
{"type":"Feature","properties":{"OBJECTID":3213,"USE":"dem","tile":"4045644",
"NOSW":"4045646 NV NV NV"
}},
{"type":"Feature","properties":{"OBJECTID":3214,"USE":"dem","tile":"4045646",
"NOSW":"4045648 NV 4045644 NV"
}},
{"type":"Feature","properties":{"OBJECTID":3215,"USE":"dem","tile":"4045648",
"NOSW":"4045650 NV 4045646 NV"
}}
]
}
CodePudding user response:
If you only use map
then for each element you end up iterating over all arguments again. Instead, you have to align the .features
array to the $ARGS.positional
array.
One way, which is closer to your attempt, is to expand the .features
array using to_entries
to fit the array's elements with their keys, which in turn can be used within map
to reference by index the corresponding item of the $ARGS.positional
array.
jq '
.features |= (to_entries | map(
.value * {properties: {NOSW: $ARGS.positional[.key]}}
))
' --args "${pushintojson[@]}" < input.json
Another approach would be to use transpose
to generate an array of aligned items from both initial arrays, and then again just map
their contents together.
jq '
.features |= ([., $ARGS.positional] | transpose | map(
.[0] * {properties: {NOSW: .[1]}}
))
' --args "${pushintojson[@]}" < input.json
Both produce
{
"type": "FeatureCollection",
"name": "test",
"features": [
{
"type": "Feature",
"properties": {
"OBJECTID": 3213,
"USE": "dem",
"tile": "4045644",
"NOSW": "4045646 NV NV NV"
}
},
{
"type": "Feature",
"properties": {
"OBJECTID": 3214,
"USE": "dem",
"tile": "4045646",
"NOSW": "4045648 NV 4045644 NV"
}
},
{
"type": "Feature",
"properties": {
"OBJECTID": 3215,
"USE": "dem",
"tile": "4045648",
"NOSW": "4045650 NV 4045646 NV"
}
}
]
}