Skip to content

Instantly share code, notes, and snippets.

@nhed
Created December 22, 2024 05:07
Show Gist options
  • Save nhed/aee8300940b1781d9e66e176e5dcc1ca to your computer and use it in GitHub Desktop.
Save nhed/aee8300940b1781d9e66e176e5dcc1ca to your computer and use it in GitHub Desktop.
# Two functions for reading multiple variables out of a json stream with a single `jq` execution
# One reads them to an associated array and one to named vars
# Extract certain fields from json (STDIN) to a bash associated array
# Args:
# - out (nameref assoc-array) where results are written to.
# - rest is pairs of jq expressions to aa keys (to index into "out").
# The jq expressions must result in leaf-values that can be printed.
function json2aa {
if [[ "$(declare -p "${1}")" != "declare -A"* ]]; then
echo "json2aa: passed nameref (${1}) is not of an associated array" >&2
return 1
fi
local -n out="${1}"; shift
local -a keys=()
local jq_expr='['
if [ $(( ${#} % 2 )) -ne 0 ]; then
echo "json2aa: not en even number of remaining args" >&2
return 1
fi
while [ ${#} -ge 2 ]; do
jq_expr+="${1}"; shift
keys+=( "${1}" ); shift
[ ${#} -gt 1 ] && jq_expr+=','
done
jq_expr+='] | join("\n")'
# now jq_expr should be an array of expressions that is then 'join'ed with newlines
local -i idx=0
local value
while read -r value; do
out["${keys[idx]}"]="${value}"
(( idx++ ))
done < <(jq -r "${jq_expr}")
return 0
}
# Extract certain fields from json (STDIN) to a bash associated array
# Args are pairs of jq expressions and variable namerefs.
# The jq expressions must result in leaf-values that can be printed.
# The variables are expected to exist in caller's scope
function read_json {
local -a names=()
local jq_expr='['
if [ $(( ${#} % 2 )) -ne 0 ]; then
echo "json2aa: not en even number of remaining args" >&2
return 1
fi
while [ ${#} -ge 2 ]; do
names+=( "${1}" ); shift
jq_expr+="${1}"; shift
[ ${#} -gt 1 ] && jq_expr+=','
done
jq_expr+='] | join("\n")'
# now jq_expr should be an array of expressions that is then 'join'ed with newlines
local -i idx=0
local value
while read -r value; do
local -n var="${names[idx]}"
var="${value}"
(( idx++ ))
done < <(jq -r "${jq_expr}")
return 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment