2016-06-16 20 views
3

ich eine einfachen Bash-Funktion geschrieben, den Wert aus einer INI-Datei lesen würde (definiert durch Variable CONF_FILE) und Ausgabe, die esLese Wert aus einer INI-Stil-Datei mit sed/awk

getConfValue() { 
#getConfValue section variable 
#return value of a specific variable from given section of a conf file 
section=$1 
var="$2" 
val=$(sed -nr "/\[$section\]/,/\[/{/$var/p}" $CONF_FILE) 
val=${val#$var=} 
echo "$val" 
} 

Das Problem ist, dass es funktioniert Kommentare nicht ignorieren und Probleme verursachen, wenn mehrere Variablen innerhalb eines Abschnitts gemeinsame Teilstrings enthalten.

Beispiel ini-Datei:

[general] 
# TEST=old 
; TEST=comment 
TEST=new 
TESTING=this will be output too 
PATH=/tmp/test 

Lauf getConfValue general PATH würde Ausgang /tmp/test wie erwartet, aber läuft getConfValue general TEST zeigt alle Probleme dieser Ansatz hat.

Wie behebt man das?

Ich weiß, es gibt dedizierte Tools wie crudini oder Tools für Python, Perl und PHP in freier Wildbahn, aber ich möchte keine zusätzlichen Abhängigkeiten für einfache Konfig Dateianalyse hinzufügen. Eine Lösung mit awk anstelle von sed wäre auch in Ordnung.

Antwort

5

Kleben mit sed könnten Sie Ihre var Suche nach dem Beginn der Aufzeichnung verankern ^ verwenden und es mit einem Gleichheitszeichen enden:

"/\[$section\]/,/\[/{/^$var=/p}" 

Wenn Sie Leerzeichen vor Ihrem Datensatz besorgt sind Sie verantwortlich sein könnten dafür:

"/\[$section\]/,/\[/{/^(\W|)$var=/p}" 

die ^(\W|)$var= sagt „, wenn es Leerzeichen am Anfang (^(\W) oder nichts (|)) vor Ihre Variable ist mit einem Gleichheitszeichen verkettet ($var=). "

Wenn Sie wollen Sie so etwas wie nutzen könnten, um awk wechseln:

val=$(awk -F"=" -v section=$section -v var=$var '$1=="["section"]"{secFound=1}secFound==1 && $1==var{print $2; secFound=0}' $CONF_FILE) 

Die awk Befehl, um die Aufzeichnung von gleich -F"=" aufteilt. Dann, wenn das erste Feld im Datensatz ist Ihre Sektion ($1=="["section"]") dann setzen Sie Variable secFound auf 1. Dann ... wenn secFound ist 1 und das erste Feld ist genau gleich var Variable (secFound==1 && $1==var) dann drucken Sie das zweite Feld ({print $2}) und setzt secFound auf 0, damit wir keine anderen Test Schlüssel aufnehmen.

+0

Danke! Das funktioniert gut. Das einzige Problem dieses Ansatzes ist, dass es fehlschlägt, wenn Leerzeichen (oder Tabulatoren) vor dem Variablennamen stehen. Ist es möglich, etwas wie "" * zum Suchstring hinzuzufügen? – smihael

+0

Ich aktualisiert mit einem 'sed' Beispiel, das Leerzeichen vor dem Schlüssel/Wert-Paar berücksichtigt. – JNevill