¿Hay alguna forma de crear pares clave-valor en el script Bash?

82

Estoy tratando de crear un diccionario de pares clave-valor usando el script Bash. Estoy tratando de usar esta lógica:

declare -d dictionary
defaults write "$dictionary" key -string "$value"

... donde $dictionaryes una variable, pero esto no funciona.

¿Hay alguna forma de crear pares clave-valor en el script Bash?

RKS
fuente
estaba trabajando en bash. Descubrí una manera de hacer esto yo mismo.
RKS
el uso de esto también ayuda: urls + = ('<dict> <key> key1 </key> <string>' $ value1 '</string> <key> key2 </key> <string>' $ value2 '</ string > <key> key3 </key> <string> '$ value3' </string> </dict> '
RKS
3
¡Excelente! Se le permite (e incluso se le anima) a responder sus propias preguntas en StackOverflow, de esa manera ayudará a otros en una situación similar.
Johnsyweb
Votaré su respuesta si incluye algún uso y salida de muestra. Buena suerte.
shellter

Respuestas:

154

En la versión 4 de bash se introdujeron matrices asociativas.

declare -A arr

arr["key1"]=val1

arr+=( ["key2"]=val2 ["key3"]=val3 )

La matriz arr ahora contiene los tres pares clave-valor. Sin embargo, Bash es bastante limitado en lo que puede hacer con ellos, sin clasificar o hacer estallar, etc.

for key in ${!arr[@]}; do
    echo ${key} ${arr[${key}]}
done

Recorrerá todos los valores clave y los repetirá.

Nota: Bash 4 no viene con Mac OS X debido a su licencia GPLv3; tienes que descargarlo e instalarlo. Para más sobre eso, vea aquí

peteches
fuente
25
Es importante notar que Bash 4 no viene con Mac OS X debido a su licencia GPLv3; tienes que descargarlo e instalarlo. (Apple todavía envía Bash 3.2.)
favor
5
Aquí hay una desventaja: la iteración no está ordenada por orden de inserción.
AlikElzin-kilaka
definitivamente necesita bash versión 4. De lo contrario, declare -A no funciona. Mac viene con bash 3.2
Mamun
2
No es por la licencia GPLv3 sino porque Apple no quiere usar software con licencia GPLv3. Así que no hay nada de malo con la licencia GPLv3, pero sí con Apple, supongo.
Tech Nomad
32

Si puede usar un delimitador simple, un delimitador muy simple es este:

for i in a,b c_s,d ; do 
  KEY=${i%,*};
  VAL=${i#*,};
  echo $KEY" XX "$VAL;
done

Por la presente iestá lleno de secuencias de caracteres como "a,b"y "c_s,d". cada uno separado por espacios. Después de doque usamos la sustitución de parámetros para extraer la parte antes de la coma ,y la parte posterior.

matemáticas
fuente
¿Puede explicar el ejemplo que dio?
AlikElzin-kilaka
Pregunta: ¿Funcionará si bes una variable que contiene espacios?
AlikElzin-kilaka
en mi ejemplo, b no es una variable, y no, no funcionará, ya que la lista del bucle for está separada por espacios.
matemáticas
2

Para el almacenamiento persistente de clave / valor, puede usar kv-bashuna implementación bash pura de la base de datos de clave / valor disponible en https://github.com/damphat/kv-bash

Uso

git clone https://github.com/damphat/kv-bash
source kv-bash/kv-bash

Intenta crear algunas variables permanentes

kvset myName  xyz
kvset myEmail [email protected]

#read the varible
kvget myEmail

#you can also use in another script with $(kvget keyname)
echo $(kvget myEmail)
andrej
fuente
2

En bash, usamos

declare -A name_of_dictonary_variable

para que Bash entienda que es un diccionario.

Por ejemplo, si desea crear un soundsdiccionario,

declare -A sounds

sounds[dog]="Bark"

sounds[wolf]="Howl"

dónde dogy wolfson "keys"y Barky Howlson "values".

Puede acceder a todos los valores usando: echo ${sounds[@]}Oecho ${sounds[*]}

Puede acceder a todas las claves solo usando: echo ${!sounds[@]}

Y si desea algún valor para una clave en particular, puede usar:

${sounds[dog]}

esto le dará valor ( Bark) para clave ( Dog).

Ruchir Dixit
fuente
0

en bash anterior (o en sh) que no es compatible declare -A, el siguiente estilo se puede usar para emular clave / valor

# key
env=staging


# values
image_dev=gcr.io/abc/dev
image_staging=gcr.io/abc/stage
image_production=gcr.io/abc/stable

img_var_name=image_$env

# active_image=${!var_name}
active_image=$(eval "echo \$$img_var_name")

echo $active_image
romanlv
fuente