Assuming you want to use the key as part of the variable name, and that the key always has a sane value that can be used as part of a shell variable's name (we will not be verifying this), and that the name
key holds a scalar that can be used as the value in a shell variable:
$ input='{"person1": {"name": "foo"}, "person2": {"name": "bar"}}'
$ eval "$(jq -n -r --argjson data "$input" '$data | to_entries[] | @sh "export \(.key)_name=\(.value.name)"')"
$ printf '%s\n' "$person1_name" "$person2_name"
foo
bar
This uses jq
to create output like
export 'person1'_name='foo'
export 'person2'_name='bar'
... given the keys and the name
sub-keys document passed as the jq
variable $data
.
The @sh
output operator does some basic handling of shell escapes, which means that this also handles the cases where a name contains tabs, newlines, and quotes:
$ input='{"person1": {"name": "foo\tbar\nthe third"}, "person2": {"name": "A'\''Tuin"}}'
$ eval "$(jq -n -r --argjson data "$input" '$data | to_entries[] | @sh "export \(.key)_name=\(.value.name)"')"
$ printf '%s\n' "$person1_name" "$person2_name"
foo bar
the third
A'Tuin
A jq
command that creates the variable names in the format shown in the question, with the number counting up with each person:
$ jq -n -r --argjson data "$input" 'reduce ($data|to_entries[]) as $e ([]; . += [@sh "export PERSON_\(1+length)_NAME=\($e.value.name)"]) | .[]'
export PERSON_1_NAME='foo'
export PERSON_2_NAME='bar'