BASH Variables de análisis desde el archivo de configuración

Tener el siguiente contenido en un archivo:

VARIABLE1="Value1" VARIABLE2="Value2" VARIABLE3="Value3" 

Necesito un script que muestre lo siguiente:

 Content of VARIABLE1 is Value1 Content of VARIABLE2 is Value2 Content of VARIABLE3 is Value3 

¿Algunas ideas?

awk -F\= '{gsub(/"/,"",$2);print "Content of " $1 " is " $2}'

Solo para tu información, otra solución pura bash

 IFS="=" while read -r name value do echo "Content of $name is ${value//\"/}" done < filename 

Como su archivo de configuración es un script de shell válido, puede buscarlo en su shell actual:

 . config_file echo "Content of VARIABLE1 is $VARIABLE1" echo "Content of VARIABLE2 is $VARIABLE2" echo "Content of VARIABLE3 is $VARIABLE3" 

Ligeramente DRYer, pero más complicado

 . config_file for var in VARIABLE1 VARIABLE2 VARIABLE3; do echo "Content of $var is ${!var}" done 

Si necesitas estos …

Caracteristicas

  • Una línea y comentarios en línea;
  • Recortar espacios alrededor de = (es decir, var = value no fallará);
  • Valores de cadena entre comillas;
  • Comprender los finales de línea de DOS;
  • Manténgase seguro, evitando el abastecimiento de su archivo de configuración.

Código

 shopt -s extglob configfile="dos_or_unix" # set the actual path name of your (DOS or Unix) config file tr -d '\r' < $configfile > $configfile.unix while IFS='= ' read -r lhs rhs do if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then rhs="${rhs%%\#*}" # Del in line right comments rhs="${rhs%%*( )}" # Del trailing spaces rhs="${rhs%\"*}" # Del opening string quotes rhs="${rhs#\"*}" # Del closing string quotes declare $lhs="$rhs" fi done < $configfile.unix 

Comentarios

tr -d '\r' ... elimina el retorno de carro de DOS.
! $lhs =~ ^\ *# ! $lhs =~ ^\ *# omite los comentarios de una sola línea y -n $lhs omite las líneas vacías.
La eliminación de espacios finales con ${rhs%%*( )} requiere la configuración de globbing extendido con shopt -s extglob . (Aparte de usar sed ), puedes evitar esto, a través de los más complejos:

 rhs="${rhs%"${rhs##*[^ ]}"}" 

Archivo de configuración de prueba

 ## This is a comment var1=value1 # Right side comment var2 = value2 # Assignment with spaces ## You can use blank lines var3= Unquoted String # Outer spaces trimmed var4= "My name is " # Quote to avoid trimming var5= "\"Bob\"" 

Código de prueba

 echo "Content of var1 is $var1" echo "Content of var2 is $var2" echo "Content of var3 is [$var3]" echo "Content of var4 + var5 is: [$var4$var5]" 

Resultados

 Content of var1 is value1 Content of var2 is value2 Content of var3 is [Unquoted String] Content of var4 + var5 is: [My name is "Bob"] 

Lo hago de esta manera

 . $PATH_TO_FILE 
 awk '{print "Content of "$1" is "$3}' FS='[="]' 

Resultado

 El contenido de VARIABLE1 es Value1
 El contenido de VARIABLE2 es Value2
 El contenido de VARIABLE3 es Value3
  # #------------------------------------------------------------------------------ # parse the ini like $0.$host_name.cnf and set the variables # cleans the unneeded during after run-time stuff. Note the MainSection # courtesy of : http://mark.aufflick.com/blog/2007/11/08/parsing-ini-files-with-sed #------------------------------------------------------------------------------ doParseConfFile(){ # set a default cnfiguration file cnf_file="$run_unit_bash_dir/$run_unit.cnf" # however if there is a host dependant cnf file override it test -f "$run_unit_bash_dir/$run_unit.$host_name.cnf" \ && cnf_file="$run_unit_bash_dir/$run_unit.$host_name.cnf" # yet finally override if passed as argument to this function # if the the ini file is not passed define the default host independant ini file test -z "$1" || cnf_file=$1;shift 1; test -z "$2" || ini_section=$2;shift 1; doLog "DEBUG read configuration file : $cnf_file" doLog "INFO read [$ini_section] section from config file" # debug echo "@doParseConfFile cnf_file:: $cnf_file" # coud be later on parametrized ... test -z "$ini_section" && ini_section='MAIN_SETTINGS' doLog "DEBUG reading: the following configuration file" doLog "DEBUG ""$cnf_file" ( set -o posix ; set ) | sort >"$tmp_dir/vars.before" eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \ -e 's/#.*$//' \ -e 's/[[:space:]]*$//' \ -e 's/^[[:space:]]*//' \ -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \ < $cnf_file \ | sed -n -e "/^\[$ini_section\]/,/^\s*\[/{/^[^#].*\=.*/p;}"` ( set -o posix ; set ) | sort >"$tmp_dir/vars.after" doLog "INFO added the following vars from section: [$ini_section]" cmd="$(comm -3 $tmp_dir/vars.before $tmp_dir/vars.after | perl -ne 's#\s+##g;print "\n $_ "' )" echo -e "$cmd" echo -e "$cmd" >> $log_file echo -e "\n\n" sleep 1; printf "\033[2J";printf "\033[0;0H" # and clear the screen } #eof func doParseConfFile 

dado un archivo de configuración de la siguiente manera:

 [a] b=C d=E;rm t1 [b] g=h 

el siguiente one-liner analizará y mantendrá los valores:

 CFG=path-to-file; for ini in `awk '/^\[/' $CFG`;do unset ARHG;declare -A ARHG;while read AB;do ARHG[$A]=$B;echo "in section $ini, $A is equal to" ${ARHG["$A"]};done < <(awk -F'=' '/\[/ {x=0} x==1 && $0~/=/ && NF==2 {print $1, $2} $0==INI {x=1}' INI="$ini" $CFG);declare -p ARHG;echo;done;printf "end loop\n\n";declare -p ARHG 

Ahora, vamos a romper eso

 CFG=path-to-file; for ini in `awk '/^\[/' $CFG` # finds the SECTIONS (aka "ini") do unset ARHG # resets ARHG declare -A ARHG # declares an associative array while read AB do ARHG[$A]=$B echo "in section $ini, $A is equal to" ${ARHG["$A"]} done < <(awk -F'=' '/\[/ {x=0} x==1 && $0~/=/ && NF==2 {print $1, $2} $0==INI {x=1}' INI="$ini" $CFG) # the awk splits the file into sections, # and returns pairs of values separated by "=" declare -p ARHG # displays the current contents of ARHG echo done printf "end loop\n\n" declare -p ARHG 

Esto nos permite guardar valores, sin usar eval o backtick. Para estar "realmente limpio", podríamos eliminar [: espacio:] al principio y al final de la línea, ignorar las líneas "^ #" y eliminar espacios alrededor del signo "igual".