Jeśli masz dostępnego Gita i nie masz możliwości używania podkreślników w nazwach kluczy, możesz użyć go git config
jako ogólnego analizatora składni / edytora INI.
Zajmie się parsowaniem pary klucz / wartość z całego =
i odrzuci nieznaczne białe znaki, a także otrzymasz komentarze (zarówno ;
i #
), jak i wpisz przymus w zasadzie za darmo. .ini
Poniżej zamieściłem pełny działający przykład danych wejściowych OP i pożądanych wyników (tablice asocjacyjne Bash).
Jednak biorąc pod uwagę taki plik konfiguracyjny
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
… Pod warunkiem, że potrzebujesz tylko szybkiego i brudnego rozwiązania i nie jesteś żonaty z pomysłem posiadania ustawień w tablicy asocjacyjnej Bash, możesz uciec z tak małą ilością:
eval $(git config -f mytool.ini --list | tr . _)
# or if 'eval' skeeves you out excessively
source <(git config -f mytool.ini --list | tr . _)
który tworzy zmienne środowiskowe nazwane sectionname_variablename
w bieżącym środowisku. Działa to oczywiście tylko wtedy, gdy możesz ufać, że żadna z twoich wartości nigdy nie będzie zawierała kropki ani spacji (zobacz poniżej bardziej niezawodne rozwiązanie).
Inne proste przykłady
Pobieranie dowolnych wartości za pomocą funkcji powłoki w celu zapisania pisania:
function myini() { git config -f mytool.ini; }
Alias też byłby w tym przypadku OK, ale zwykle nie są one rozszerzane w skrypcie powłoki [ 1 ], a jednak aliasy są zastępowane przez funkcje powłoki „do prawie wszystkich celów” [ 2 ], zgodnie ze stroną podręcznika użytkownika Bash .
myini --list
# result:
# section1.inputdir=~/some/dir
# section1.enablesomefeature=true
# section1.enablesomeotherfeature=yes
# section2.anothersetting=42
myini --get section1.inputdir
# result:
# ~/some/dir
Dzięki tej --type
opcji możesz „kanonizować” określone ustawienia jako liczby całkowite, logiczne lub ścieżki (automatycznie rozwijane ~
):
myini --get --type=path section1.inputdir # value '~/some/dir'
# result:
# /home/myuser/some/dir
myini --get --type=bool section1.enablesomeotherfeature # value 'yes'
# result:
# true
Nieco bardziej solidny przykład szybkiego i brudnego
Udostępnij wszystkie zmienne mytool.ini
jak SECTIONNAME_VARIABLENAME
w bieżącym środowisku, zachowując wewnętrzne spacje w kluczowych wartościach:
source <(
git config -f mytool.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/\U\1_\2\E="\3"/'
)
To, co robi wyrażenie sed, po angielsku, jest
- znajdowanie grupy nie-kropkowych znaków aż do kropki, pamiętając to jako
\1
wtedy
- znalezienie grupy znaków aż do znaku równości, pamiętając, że jako
\2
i
- znalezienie wszystkich znaków po znaku równości jako
\3
- wreszcie w ciągu zastępującym
- nazwa sekcji + nazwa zmiennej ma wielkie litery, oraz
- część wartości jest cytowana podwójnie, w przypadku gdy zawiera znaki, które mają specjalne znaczenie dla powłoki, jeśli nie są cytowane (jak białe znaki)
Te \U
i \E
sekwencje w ciągu zastępowania (które wielkimi literami, że część napisu zastępczego) są GNU sed
rozszerzeń. W systemach macOS i BSD wystarczy użyć wielu -e
wyrażeń, aby uzyskać ten sam efekt.
Postępowanie z osadzonymi cytatami i białymi znakami w nazwach sekcji (co git config
pozwala) pozostawia się jako ćwiczenie dla czytelnika.:)
Używanie nazw sekcji jako kluczy w tablicy asocjacyjnej Bash
Dany:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
Spowoduje to wynik, o który prosi OP, po prostu przez zmianę niektórych ujęć w wyrażeniu zastępującym sed, i będzie działał dobrze bez GNU sed:
source <(
git config -f foo.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/declare -A \2["\1"]="\3"/'
)
Przewiduję, że mogą istnieć pewne problemy z cytowaniem rzeczywistego .ini
pliku, ale działa on na podany przykład. Wynik:
declare -p {session,path}
# result:
# declare -A session=([barfoo]="bar" [foobar]="foo" )
# declare -A path=([barfoo]="/some/path" [foobar]="/some/path" )