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 configals 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 .iniunten 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_variablenamein 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 --typeOption 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.iniwie SECTIONNAME_VARIABLENAMEin 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
\1dann
- 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 \Uund \Ein der Ersetzungszeichenfolge (die den Teil der Ersetzungszeichenfolge in Großbuchstaben angibt) sind GNU- sedErweiterungen. Unter MacOS und BSD verwenden Sie einfach mehrere -eAusdrücke, um den gleichen Effekt zu erzielen.
Der Umgang mit eingebetteten Anführungszeichen und Leerzeichen in den Abschnittsnamen (was git configerlaubt) 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 .iniDatei 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" )