Wenn Sie Git zur Verfügung haben und mit der Einschränkung zufrieden sind, Unterstriche in den Schlüsselnamen nicht verwenden zu können, können Sie es git config
als allgemeinen INI-Parser / -Editor verwenden.
Es behandelt das Parsen des Schlüssel / Wert-Paares von =
und verwirft unbedeutende Leerzeichen. Außerdem erhalten Sie Kommentare (sowohl ;
als auch #
) und geben Nötigung grundsätzlich kostenlos ein. Ich habe .ini
unten ein vollständiges Arbeitsbeispiel für die Eingabe und die gewünschte Ausgabe des OP (Bash-assoziative Arrays) beigefügt .
Gegeben ist jedoch eine solche Konfigurationsdatei
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
… Vorausgesetzt, Sie brauchen nur eine schnelle und schmutzige Lösung und sind nicht mit der Idee verbunden, die Einstellungen in einem assoziativen Bash-Array zu haben.
eval $(git config -f mytool.ini --list | tr . _)
# or if 'eval' skeeves you out excessively
source <(git config -f mytool.ini --list | tr . _)
Dadurch werden Umgebungsvariablen erstellt, die sectionname_variablename
in der aktuellen Umgebung benannt sind. Dies funktioniert natürlich nur, wenn Sie darauf vertrauen können, dass keiner Ihrer Werte jemals einen Punkt oder ein Leerzeichen enthält (siehe unten für eine robustere Lösung).
Andere einfache Beispiele
Abrufen beliebiger Werte mithilfe einer Shell-Funktion zum Speichern der Eingabe:
function myini() { git config -f mytool.ini; }
Ein Alias wäre auch hier in Ordnung, aber diese werden normalerweise nicht in einem Shell-Skript [ 1 ] erweitert, und Aliasnamen werden von Shell-Funktionen "für fast jeden Zweck" [ 2 ] gemäß der Manpage von Bash abgelöst .
myini --list
# result:
# section1.inputdir=~/some/dir
# section1.enablesomefeature=true
# section1.enablesomeotherfeature=yes
# section2.anothersetting=42
myini --get section1.inputdir
# result:
# ~/some/dir
Mit dieser --type
Option können Sie bestimmte Einstellungen als Ganzzahlen, Boolesche Werte oder Pfade "kanonisieren" (automatisch erweitern ~
):
myini --get --type=path section1.inputdir # value '~/some/dir'
# result:
# /home/myuser/some/dir
myini --get --type=bool section1.enablesomeotherfeature # value 'yes'
# result:
# true
Etwas robusteres Quick-and-Dirty-Beispiel
Stellen Sie alle Variablen in mytool.ini
wie SECTIONNAME_VARIABLENAME
in der aktuellen Umgebung zur Verfügung, und behalten Sie dabei das interne Leerzeichen in den Schlüsselwerten bei:
source <(
git config -f mytool.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/\U\1_\2\E="\3"/'
)
Was der sed-Ausdruck auf Englisch tut, ist
- Finden einer Gruppe von Nicht-Punkt-Zeichen bis zu einem Punkt, wobei man sich daran erinnert, dass
\1
dann
- eine Reihe von Zeichen bis zu einem Gleichheitszeichen finden, sich daran erinnern, als
\2
, und
- Suche nach allen Zeichen nach dem Gleichheitszeichen als
\3
- schließlich in der Ersatzzeichenfolge
- Der Abschnittsname + Variablenname wird in Großbuchstaben geschrieben
- Der Wertteil wird in doppelte Anführungszeichen gesetzt, wenn er Zeichen enthält, die für die Shell eine besondere Bedeutung haben, wenn er nicht in Anführungszeichen gesetzt wird (wie Leerzeichen).
Die Sequenzen \U
und \E
in der Ersetzungszeichenfolge (die den Teil der Ersetzungszeichenfolge in Großbuchstaben angibt) sind GNU- sed
Erweiterungen. Unter MacOS und BSD verwenden Sie einfach mehrere -e
Ausdrücke, um den gleichen Effekt zu erzielen.
Der Umgang mit eingebetteten Anführungszeichen und Leerzeichen in den Abschnittsnamen (was git config
erlaubt) wird dem Leser als Übung überlassen.:)
Verwenden von Abschnittsnamen als Schlüssel in einem assoziativen Bash-Array
Gegeben:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
Dies führt zu dem vom OP gewünschten Ergebnis, indem einfach einige der Captures im sed-Ersetzungsausdruck neu angeordnet werden. Ohne GNU sed funktioniert dies problemlos:
source <(
git config -f foo.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/declare -A \2["\1"]="\3"/'
)
Ich gehe davon aus, dass das Zitieren einer realen .ini
Datei einige Probleme mit sich bringen könnte , aber es funktioniert für das angegebene Beispiel. Ergebnis:
declare -p {session,path}
# result:
# declare -A session=([barfoo]="bar" [foobar]="foo" )
# declare -A path=([barfoo]="/some/path" [foobar]="/some/path" )