Investigamos en todo el mundo on line y de este modo mostrarte la respuesta a tu problema, si tienes preguntas déjanos tu duda y responderemos porque estamos para ayudarte.
Solución:
Si quieres key y valor, y basado en ¿Cómo convierto un objeto json a key= formato de valor en JQ, puede hacer:
$ jq -r "to_entries|map("(.key)=(.value|tostring)")|.[]" file
SALUTATION=Hello world
SOMETHING=bla bla bla Mr. Freeman
De una manera más general, puede almacenar los valores en un array myarray[key] = value
así, simplemente proporcionando jq
al while
con el while ... do; ... done < <(command)
sintaxis:
declare -A myarray
while IFS="=" read -r key value
do
myarray[$key]="$value"
done < <(jq -r 'to_entries|map("(.key)=(.value)")|.[]' file)
Y luego puede recorrer los valores de esta manera:
for key in "$!myarray[@]"
do
echo "$key = $myarray[$key]"
done
Para esta entrada dada, devuelve:
SALUTATION = Hello world
SOMETHING = bla bla bla Mr. Freeman
Aunque se respondió esta pregunta, no pude satisfacer completamente mis requisitos con la respuesta publicada. Aquí hay una pequeña reseña que ayudará a los recién llegados a bash.
Presciencia
Un asociativo básico array declaración
#!/bin/bash
declare -A associativeArray=([key1]=val1 [key2]=val2)
También puede utilizar comillas ('
, "
) alrededor de declaration
, su keys
, y
values
.
#!/bin/bash
declare -A 'associativeArray=([key1]=val1 [key2]=val2)'
Y puedes delimitar cada uno [key]=value
emparejar a través de espacio o nueva línea.
#!/bin/bash
declare -A associativeArray([key1]=value1
['key2']=value2 [key3]='value3'
['key4']='value2' ["key5"]="value3"
["key6"]='value4'
['key7']="value5"
)
Dependiendo de la variación de su cotización, es posible que deba escapar de su string.
Usando Indirection para acceder a ambos key y valor en un asociativo array
example ()
local -A associativeArray=([key1]=val1 [key2]=val2)
# print associative array
local key value
for key in "$!associativeArray[@]"; do
value="$associativeArray["$key"]"
printf '%s = %s' "$key" "$value"
done
Ejecutando la función de ejemplo
$ example
key2 = val2
key1 = val1
Conocer los datos mencionados anteriormente le permite derivar los siguientes fragmentos:
Los siguientes ejemplos tendrán todos el resultado del ejemplo anterior.
Evaluación de cadenas
#!/usr/bin/env bash
example ()
local arrayAsString='associativeArray=([key1]=val1 [key2]=val2)'
local -A "$arrayAsString"
# print associative array
Canalizando su JSON en JQ
#!/usr/bin/env bash
# Note: usage of single quotes instead of double quotes for the jq
# filter. The former is preferred to avoid issues with shell
# substitution of quoted strings.
example () map("[(.key)]=(.value)")
jq -n / -null-opción de entrada + --argfile && redirección
#!/usr/bin/env bash
example () @sh)]
Revisar respuestas anteriores
@ Ján Lalinský
Para cargar un objeto JSON en un bash asociativo array de manera eficiente (sin usar bucles en bash), se puede usar la herramienta 'jq', de la siguiente manera.
# first, load the json text into a variable: json='"SALUTATION": "Hello world", "SOMETHING": "bla bla bla Mr. Freeman"' # then, prepare associative array, I use 'aa': unset aa declare -A aa # use jq to produce text defining name:value pairs in the bash format # using @sh to properly escape the values aacontent=$(jq -r '. | to_entries | .[] | "["" + .key + ""]=" + (.value | @sh)' <<< "$json") # string containing whole definition of aa in bash aadef="aa=($aacontent)" # load the definition (because values may contain LF characters, aadef must be in double quotes) eval "$aadef" # now we can access the values like this: echo "$aa[SOMETHING]"
Advertencia: esto usa eval, que es peligroso si la entrada json es de una fuente desconocida (puede contener comandos de shell maliciosos que eval puede ejecutar).
Esto podría reducirse a lo siguiente
example () to_entries
@fedorqui
Si quieres key y valor, y basado en ¿Cómo convierto un objeto json a key= formato de valor en JQ, puede hacer:
$ jq -r "to_entries|map("(.key)=(.value|tostring)")|.[]" file SALUTATION=Hello world SOMETHING=bla bla bla Mr. Freeman
De una manera más general, puede almacenar los valores en un array
myarray[key] = value
así, simplemente proporcionandojq
alwhile
con elwhile ... do; ... done < <(command)
sintaxis:declare -A myarray while IFS="=" read -r key value do myarray[$key]="$value" done < <(jq -r "to_entries|map("(.key)=(.value)")|.[]" file)
Y luego puede recorrer los valores de esta manera:
for key in "$!myarray[@]" do echo "$key = $myarray[$key]" done
Para esta entrada dada, devuelve:
SALUTATION = Hello world SOMETHING = bla bla bla Mr. Freeman
La principal diferencia entre esta solución y la mía es recorrer el
array en bash o en jq.
Cada solución es válida y, dependiendo de su caso de uso, una puede ser más útil que la otra.
Contexto: esta respuesta se escribió para responder a un título de pregunta que ya no existe..
La pregunta del OP en realidad describe objetos, frente a matrices.
Para asegurarnos de que ayudamos a otras personas que vienen Realmente Sin embargo, si busca ayuda con las matrices JSON, vale la pena cubrirlas explícitamente.
Para el caso seguro donde las cadenas no pueden contener líneas nuevas (y cuando se usa bash 4.0 o más reciente), esto funciona:
str='["Hello world", "bla bla bla Mr. Freeman"]'
readarray -t array <<<"$(jq -r '.[]' <<<"$str")"
Para admitir versiones anteriores de bash y cadenas con nuevas líneas, nos volvemos un poco más elegantes, utilizando una secuencia delimitada por NUL para leer jq
:
str='["Hello world", "bla bla bla Mr. Freeman", "this isntwo lines"]'
array=( )
while IFS= read -r -d '' line; do
array+=( "$line" )
done < <(jq -j '.[] | (. + "u0000")')