Próbuję przekonwertować plik INI na zmienne tablicy bash. Przykładowy ini jest jak poniżej:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
więc stają się one:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
i tak dalej.
W tej chwili mogłem wymyślić tylko to polecenie
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Innym problemem jest to, że nie bierze pod =
uwagę miejsc w pobliżu . Myślę, że sed
prawdopodobnie lepiej nadaje się do tego zadania, ale nie wiem, jak przechowywać i przechowywać zmienną tymczasową dla nazwy sekcji sed
.
Więc jakiś pomysł, jak to zrobić?
ini
parsera wbash
.Odpowiedzi:
Gawk akceptuje wyrażenia regularne jako ograniczniki pól. Poniższe eliminuje spacje wokół znaku równości, ale zachowuje je w pozostałej części wiersza. Wokół wartości dodawane są cudzysłowy, więc te spacje, jeśli istnieją, są zachowywane podczas wykonywania przypisania Bash. Zakładam, że nazwy sekcji będą zmiennymi numerycznymi, ale jeśli używasz Bash 4, łatwo byłoby to przystosować do używania tablic asocjacyjnych z samymi nazwami sekcji jako indeksami.
Zauważ, że możesz również chcieć usunąć spację, którą pokazuje Khaled (tylko 1 $ i sekcja), ponieważ nazwy zmiennych Bash nie mogą zawierać spacji.
Ponadto ta metoda nie będzie działać, jeśli wartości zawierają znaki równości.
Inną techniką byłoby użycie
while read
pętli Bash i wykonywanie przypisań podczas odczytywania pliku, przy użyciudeclare
których jest bezpieczny przed najbardziej złośliwymi treściami.Ponownie, tablice asocjacyjne mogłyby być dość łatwo obsługiwane.
źródło
Do tego zadania użyłbym prostego skryptu python, ponieważ ma on wbudowany parser INI :
a następnie w bash:
Jasne, w awk są krótsze implementacje, ale myślę, że jest to bardziej czytelne i łatwiejsze w utrzymaniu.
źródło
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Jeśli chcesz wyeliminować dodatkowe spacje, możesz skorzystać z wbudowanej funkcji
gsub
. Możesz na przykład dodać:Spowoduje to usunięcie wszystkich spacji. Jeśli chcesz usunąć spacje na początku lub na końcu tokena, możesz użyć
źródło
Oto czyste rozwiązanie bash.
To jest nowa i ulepszona wersja tego, co opublikował chilladx:
https://github.com/albfan/bash-ini-parser
Do bardzo łatwe do naśladowania początkowy przykład: Po pobraniu tego, wystarczy skopiować pliki
bash-ini-parser
, iscripts/file.ini
do tego samego katalogu, a następnie utworzyć skrypt testowy klient na przykładzie mam poniżej przewidzianego do tego samego katalogu, jak również.Oto kilka dalszych ulepszeń, które wprowadziłem do skryptu bash-ini-parser ...
Jeśli chcesz mieć możliwość odczytu plików ini z końcówkami linii Windows, a także Uniksa, dodaj ten wiersz do funkcji cfg_parser bezpośrednio po tej, która czyta plik:
Jeśli chcesz czytać pliki z ograniczonymi uprawnieniami dostępu, dodaj tę opcjonalną funkcję:
źródło
chmod 777
. Chociaż w najlepszym razie jest to podejrzana praktyka, z pewnością nie ma potrzeby, aby plik ini był wykonywalny. Lepszym podejściem byłoby użyciesudo
do odczytu pliku, a nie do bałagania się uprawnieniami.Zawsze zakładając, że istnieje ConfigParser Pythona, można zbudować funkcję pomocnika powłoki:
$IFACE
i$param
są odpowiednio sekcją parametru.Ten pomocnik umożliwia połączenia takie jak:
Mam nadzieję że to pomoże!
źródło
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
… 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ą:
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:
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 .
Dzięki tej
--type
opcji możesz „kanonizować” określone ustawienia jako liczby całkowite, logiczne lub ścieżki (automatycznie rozwijane~
):Nieco bardziej solidny przykład szybkiego i brudnego
Udostępnij wszystkie zmienne
mytool.ini
jakSECTIONNAME_VARIABLENAME
w bieżącym środowisku, zachowując wewnętrzne spacje w kluczowych wartościach:To, co robi wyrażenie sed, po angielsku, jest
\1
wtedy\2
i\3
Te
\U
i\E
sekwencje w ciągu zastępowania (które wielkimi literami, że część napisu zastępczego) są GNUsed
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:
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:
Przewiduję, że mogą istnieć pewne problemy z cytowaniem rzeczywistego
.ini
pliku, ale działa on na podany przykład. Wynik:źródło