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 ocurre este comando
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Además, otro problema es que no toma =
en cuenta los espacios cercanos . Creo que sed
probablemente sea más adecuado para este trabajo, pero no sé cómo mantener y almacenar una variable temporal para el nombre de la sección sed
.
¿Alguna idea de cómo hacer esto?
ini
analizador enbash
.Respuestas:
Gawk acepta expresiones regulares como delimitadores de campo. Lo siguiente elimina 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.
Tenga en cuenta que es posible que también desee eliminar el espacio que muestra Khaled (solo en $ 1 y sección) ya que los nombres de variables 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
while read
bucle Bash y realizar las asignaciones a medida que se lee el archivo, utilizando eldeclare
que está a salvo de la mayoría del contenido malicioso.Una vez más, las matrices asociativas podrían ser fácilmente compatibles.
fuente
Usaría un script de Python simple para este trabajo ya que ha incorporado el analizador INI :
y luego en bash:
Claro, hay implementaciones más cortas en awk, pero creo que esto es más legible y más fácil de mantener.
fuente
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Si desea eliminar los espacios adicionales, puede usar la función incorporada
gsub
. Por ejemplo, puede agregar:Esto eliminará todos los espacios. Si desea eliminar espacios al principio o al final del token, puede usar
fuente
Aquí hay una solución de bash puro.
Esta es una versión nueva y mejorada de lo que chilladx publicó:
https://github.com/albfan/bash-ini-parser
Para un ejemplo inicial realmente fácil de seguir: después de descargar esto, simplemente copie los archivos
bash-ini-parser
yscripts/file.ini
en el mismo directorio, luego cree un script de prueba del cliente usando el ejemplo que proporcioné a continuación en ese mismo directorio también.Aquí hay algunas mejoras adicionales que hice al script bash-ini-parser ...
Si desea poder leer archivos ini con terminaciones de línea de Windows y Unix, agregue esta línea a la función cfg_parser inmediatamente después de la que lee el archivo:
Si desea leer archivos que tienen permisos de acceso restrictivos, agregue esta función opcional:
fuente
chmod 777
. Si bien es una práctica sospechosa en el mejor de los casos, seguramente no hay necesidad de hacer que el archivo ini sea ejecutable. Un mejor enfoque sería usarlosudo
para leer el archivo, no meterse con los permisos.Siempre suponiendo que tenga ConfigParser de Python, uno puede construir una función auxiliar de shell como esta:
$IFACE
y$param
son la sección respectivamente el parámetro.Este ayudante luego permite llamadas como:
¡Espero que esto ayude!
fuente
Si tiene Git disponible y está de acuerdo con la restricción de no poder usar guiones bajos en los nombres de clave, puede usarlo
git config
como un analizador / editor INI de propósito general.Manejará el análisis del par clave / valor de todo el
=
espacio en blanco y descartará insignificantes, además obtendrá comentarios (ambos;
y#
) y la coerción de tipo básicamente de forma gratuita. He incluido un ejemplo de trabajo completo para la entrada del OP.ini
y la salida deseada (matrices asociativas de Bash), a continuación.Sin embargo, dado un archivo de configuración como este
... siempre que solo necesite una solución rápida y sucia, y no esté casado con la idea de tener la configuración en una matriz asociativa de Bash, puede salirse con la suya con tan solo:
que crea variables de entorno llamadas
sectionname_variablename
en el entorno actual. Esto, por supuesto, solo funciona si puede confiar en que ninguno de sus valores contendrá un punto o espacio en blanco (consulte a continuación para obtener una solución más sólida).Otros ejemplos simples
Obteniendo valores arbitrarios, usando una función de shell para guardar la escritura:
Aquí también estaría bien un alias, pero normalmente no se expanden en un script de shell [ 1 ], y de todos modos los alias son reemplazados por las funciones de shell "para casi cualquier propósito", [ 2 ], según la página del manual de Bash .
Con la
--type
opción, puede "canonizar" configuraciones específicas como enteros, booleanos o rutas (expandiéndose automáticamente~
):Ejemplo un poco más robusto, rápido y sucio
Haga que todas las variables
mytool.ini
estén disponibles comoSECTIONNAME_VARIABLENAME
en el entorno actual, conservando espacios en blanco internos en valores clave:Lo que está haciendo la expresión sed, en inglés, es
\1
, luego\2
, y\3
Las secuencias
\U
y\E
en la cadena de reemplazo (que en mayúscula esa parte de la cadena de reemplazo) sonsed
extensión GNU . En macOS y BSD, solo usaría múltiples-e
expresiones para lograr el mismo efecto.Tratar con comillas y espacios en blanco incrustados en los nombres de las secciones (lo que
git config
permite) se deja como ejercicio para el lector.:)
Usar nombres de sección como claves en una matriz asociativa de Bash
Dado:
Esto producirá el resultado que solicita el OP, simplemente reorganizando algunas de las capturas en la expresión de reemplazo de sed, y funcionará bien sin GNU sed:
Predigo que podría haber algunos desafíos al citar un
.ini
archivo del mundo real , pero funciona para el ejemplo proporcionado. Resultado:fuente