¿Cómo capturo un valor INI dentro de un script de shell?

Tengo un archivo parameters.ini, como:

[parameters.ini] database_user = user database_version = 20110611142248 

Quiero leer y usar la versión de la base de datos especificada en el archivo parameters.ini dentro de un script bash shell para poder procesarlo.

 #!/bin/sh # Need to get database version from parameters.ini file to use in script php app/console doctrine:migrations:migrate $DATABASE_VERSION 

¿Cómo haría esto?

¿Qué hay de grepping para esa línea y luego usar awk

 version=$(awk -F "=" '/database_version/ {print $2}' parameters.ini) 

Puede usar el analizador nativo bash para interpretar valores ini, de la siguiente manera:

 $ source <(grep = file.ini) 

Archivo de muestra:

 [section-a] var1=value1 var2=value2 IPS=( "1.2.3.4" "1.2.3.5" ) 

Para acceder a las variables, simplemente las imprime: echo $var1 . También puede usar matrices como se muestra arriba ( echo ${IPS[@]} ).

Si solo quieres un solo valor, solo agrégalo:

 source <(grep var1 file.ini) 

Es simple ya que no necesita ninguna biblioteca externa para analizar los datos, pero tiene algunas desventajas. Por ejemplo:

  • Si tiene espacios entre = (nombre de variable y valor), primero debe recortar los espacios primero, por ejemplo

     $ source <(grep = file.ini | sed 's/ *= */=/g') 
  • Para apoyar ; comentarios, reemplázalos con # :

     $ sed "s/;/#/g" foo.ini | source /dev/stdin 
  • Las secciones no son compatibles (por ejemplo, si tiene [section-name] , entonces tiene que filtrarlo como se muestra arriba, por ejemplo, grep = ), lo mismo para otros errores inesperados.

    Si necesita leer un valor específico en una sección específica, use grep -A , sed , awk o ex ).

    P.ej

     source <(grep = <(grep -A5 '\[section-b\]' file.ini)) 

    Nota: Donde -A5 es el número de filas para leer en la sección. Reemplace la source con cat para depurar.

  • Si tiene errores de análisis, ignórelos agregando: 2>/dev/null

Vea también: ¿Cómo analizar y convertir archivos ini en variables bash array? en serverfault SE

Bash no proporciona un analizador para estos archivos, obviamente puedes usar un código awk o un par de llamadas sed, pero si eres bash-priest y no quieres usar nada más, entonces puedes probar el siguiente código oscuro:

 #!/usr/bin/env bash cfg_parser () { ini="$(<$1)" # read the file ini="${ini//[/\[}" # escape [ ini="${ini//]/\]}" # escape ] IFS=$'\n' && ini=( ${ini} ) # convert to line-array ini=( ${ini[*]//;*/} ) # remove comments with ; ini=( ${ini[*]/\ =/=} ) # remove tabs before = ini=( ${ini[*]/=\ /=} ) # remove tabs be = ini=( ${ini[*]/\ =\ /=} ) # remove anything with a space around = ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1) ini=( ${ini[*]/=/=\( } ) # convert item to array ini=( ${ini[*]/%/ \)} ) # close array parenthesis ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2) ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis ini[0]="" # remove first element ini[${#ini[*]} + 1]='}' # add the last brace eval "$(echo "${ini[*]}")" # eval the result } cfg_writer () { IFS=' '$'\n' fun="$(declare -F)" fun="${fun//declare -f/}" for f in $fun; do [ "${f#cfg.section}" == "${f}" ] && continue item="$(declare -f ${f})" item="${item##*\{}" item="${item%\}}" item="${item//=*;/}" vars="${item//=*/}" eval $f echo "[${f#cfg.section.}]" for var in $vars; do echo $var=\"${!var}\" done done } 

Uso:

 # parse the config file called 'myfile.ini', with the following # contents:: # [sec2] # var2='something' cfg.parser 'myfile.ini' # enable section called 'sec2' (in the file [sec2]) for reading cfg.section.sec2 # read the content of the variable called 'var2' (in the file # var2=XXX). If your var2 is an array, then you can use # ${var[index]} echo "$var2" 

Bash ini-parser se puede encontrar en el sitio de blog The Old School DevOps .

Solo incluye tu archivo .ini en el cuerpo de bash:

Archivo example.ini :

 DBNAME=test DBUSER=scott DBPASSWORD=tiger 

Archivo example.sh

 #!/bin/bash #Including .ini file . example.ini #Test echo "${DBNAME} ${DBUSER} ${DBPASSWORD}" 

Sed one-liner, que tiene secciones en cuenta. Archivo de ejemplo:

 [section1] param1=123 param2=345 param3=678 [section2] param1=abc param2=def param3=ghi [section3] param1=000 param2=111 param3=222 

Digamos que quieres param2 de la sección2. Ejecute lo siguiente:

 sed -nr "/^\[section2\]/ { :l /^param2[ ]*=/ { s/.*=[ ]*//; p; q;}; n; bl;}" ./file.ini 

Te regalaré

 def 

una de las soluciones más posibles

 dbver=$(sed -n 's/.*database_version *= *\([^ ]*.*\)/\1/p' < parameters.ini) echo $dbver 

Todas las soluciones que he visto hasta ahora también afectan a las líneas comentadas. Este no, si el código de comentario es ; :

 awk -F '=' '{if (! ($0 ~ /^;/) && $0 ~ /database_version/) print $2}' file.ini 

Muestre el valor de my_key en mi_archivo de estilo ini :

 sed -n -e 's/^\s*my_key\s*=\s*//p' my_file 
  • -n – no imprime nada por defecto
  • -e – ejecuta la expresión
  • s/PATTERN//p – muestra cualquier cosa siguiendo este patrón En el patrón:
  • ^ – patrón comienza al comienzo de la línea
  • \s – personaje de espacio en blanco
  • * – cero o muchos (caracteres en blanco)

Ejemplo:

 $ cat my_file # Example INI file something = foo my_key = bar not_my_key = baz my_key_2 = bing $ sed -n -e 's/^\s*my_key\s*=\s*//p' my_file bar 

Asi que:

Encuentre un patrón donde la línea comience con cero o muchos espacios en blanco, seguido de la cadena my_key , seguido de cero o muchos espacios en blanco, un signo igual, luego cero o muchos espacios en blanco de nuevo. Muestra el rest del contenido en esa línea siguiendo ese patrón.

Para las personas (como yo) que buscan leer archivos INI a partir de scripts de shell (leer shell, no bash) – He destruido la pequeña librería auxiliar que intenta hacer exactamente eso:

https://github.com/wallyhall/shini (licencia de MIT, hazlo como quieras. He vinculado anteriormente y lo incluyo en línea porque el código es bastante extenso).

Es algo más “complicado” que las simples líneas de sed sugeridas anteriormente, pero funciona de manera muy similar.

La función lee en un archivo línea por línea, buscando marcadores de sección ( [section] ) y declaraciones de clave / valor ( key=value ).

En última instancia, recibirá una callback a su propia función: sección, clave y valor.

Puede usar la herramienta crudini para obtener valores ini, por ejemplo:

 DATABASE_VERSION=$(crudini --get parameters.ini '' database_version) 

Puede usar sed para analizar el archivo de configuración ini, especialmente cuando tiene nombres de sección como:

 # last modified 1 April 2001 by John Doe [owner] name=John Doe organization=Acme Widgets Inc. [database] # use IP address in case network name resolution is not working server=192.0.2.62 port=143 file=payroll.dat 

para que pueda usar el siguiente script sed para analizar los datos anteriores:

 # Configuration bindings found outside any section are given to # to the default section. 1 { x s/^/default/ x } # Lines starting with a #-character are comments. /#/n # Sections are unpacked and stored in the hold space. /\[/ { s/\[\(.*\)\]/\1/ x b } # Bindings are unpacked and decorated with the section # they belong to, before being printed. /=/ { s/^[[:space:]]*// s/[[:space:]]*=[[:space:]]*/|/ G s/\(.*\)\n\(.*\)/\2|\1/ p } 

esto convertirá los datos ini en este formato plano:

 owner|name|John Doe owner|organization|Acme Widgets Inc. database|server|192.0.2.62 database|port|143 database|file|payroll.dat 

por lo que será más fácil analizar mediante sed , awk o read teniendo nombres de sección en cada línea.

Créditos y fuente: archivos de configuración para scripts de shell , Michael Grünewald