Created
December 22, 2024 05:07
-
-
Save nhed/aee8300940b1781d9e66e176e5dcc1ca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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