I have the following code which reads all the fields of a Json file (the path being PRIVATE_REGISTRATION_FILE and stores them into an associative array (PRIVATE_FIELDS) which I query later in my code:
declare -A PRIVATE_FIELDS
for PRICING_FIELD in $(jq -c -r '.fields[]' "${PRIVATE_REGISTRATION_FILE}")
do
FIELD_KEY=$(jq -r '.label' <<< "${PRICING_FIELD}")
PRIVATE_FIELDS["${FIELD_KEY}"]=${PRICING_FIELD}
done
The problem is that I do this several times with several files, even though the logic is always the same.
Hence, I was thinking to extract this logic into a function but I'm having a hard time passing the map parameter to it.
This is what I attempted:
function update_array
{
FILE_NAME=$1
eval "declare -A MAP="${2#*=}
for PRICING_FIELD in $(jq -c -r '.fields[]' "${FILE_NAME}")
do
FIELD_KEY=$(jq -r '.label' <<< "${PRICING_FIELD}")
MAP["${FIELD_KEY}"]=${PRICING_FIELD}
done
}
Which I call like this:
declare -A PRIVATE_FIELDS
update_array "myFile.json" "$(declare -p PRIVATE_FIELDS)"
However it doesn't work, the map remains empty.
echo ${PRIVATE_FIELDS["someKey"]}
>>> (empty)
I have tried literally each solution proposed in this answer but none of them worked. What am I doing wrong?
Bash version: 4.2.46(2)-release
Additional note, the Json file looks like this (apparently the calls to jq may be reduced):
{
"name": "Something",
"fields": [
{
"label": "key1",
"value": "value1",
"other": "other1"
},
{
"label": "key2",
"value": "value2",
"other": "other2"
}
]
}
When you use
declarein a function, you're actually making the variable local. Seehelp declareat a bash prompt.Use a nameref (requires bash version 4.3+):
then you simply pass the array name
To more efficiently iterate over the JSON file:
That's assuming the labels don't contain any tab characters.
Using that, plus your older bash version, you can do this
Assuming that the result arrays will be in the global scope
You'd call it like