Pregunta:
Estoy tratando de convertir un archivo ini en variables de matriz bash. La muestra ini es la siguiente:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
entonces estos se convierten en:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
y así.
En este momento, solo se me ocurrió este comando
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Además, otro problema es que no tiene en cuenta los espacios cerca de =
. Creo que sed
probablemente sea más adecuado para este trabajo, pero no sé cómo retener y almacenar una variable temporal para el nombre de la sección en sed
.
Entonces, ¿alguna idea de cómo hacer esto?
Respuesta:
Gawk acepta expresiones regulares como delimitadores de campo. Lo siguiente elimina los espacios alrededor del signo igual, pero los conserva en el resto de la línea. Las comillas se agregan alrededor del valor para que esos espacios, si los hay, se conserven cuando se realiza la asignación Bash. Supongo que los nombres de las secciones serán variables numéricas, pero si está usando Bash 4, sería fácil adaptar esto para usar matrices asociativas con los nombres de las secciones como índices.
awk -F ' *= *' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" "\"" $2 "\"" }'
Tenga en cuenta que es posible que también desee eliminar el espacio que muestra Khaled (solo en $ 1 y la sección), ya que los nombres de las variables de Bash no pueden contener espacios.
Además, este método no funcionará si los valores contienen signos iguales.
Otra técnica sería utilizar un ciclo Bash while read
y realizar las asignaciones a medida que se lee el archivo, utilizando declare
cuál está a salvo de la mayoría de los contenidos maliciosos.
foobar=1
barfoo=2 # or you could increment an index variable each time a section is found
while IFS='= ' read var val
do
if [[ $var == \[*] ]]
then
section=$var
elif [[ $val ]]
then
declare "$var$section=$val"
fi
done < filename
Una vez más, las matrices asociativas podrían admitirse con bastante facilidad.