Ich versuche, eine INI-Datei in Bash-Array-Variablen zu konvertieren. Die probe ini ist wie folgt:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
so werden diese:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
und so weiter.
Im Moment konnte ich mir nur diesen Befehl einfallen lassen
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Ein weiteres Problem ist, dass Leerzeichen nicht =
berücksichtigt werden. Ich denke, es sed
ist wahrscheinlich besser für diesen Job geeignet, aber ich weiß nicht, wie ich eine temporäre Variable für den Abschnittsnamen in halten und speichern soll sed
.
Also eine Idee, wie das geht?
ini
Parser in verwendenbash
.Antworten:
Gawk akzeptiert reguläre Ausdrücke als Feldbegrenzer. Im Folgenden werden Leerzeichen um das Gleichheitszeichen entfernt, aber in der restlichen Zeile beibehalten. Um den Wert werden Anführungszeichen eingefügt, damit die Leerzeichen, sofern vorhanden, bei der Ausführung der Bash-Zuweisung erhalten bleiben. Ich gehe davon aus, dass die Abschnittsnamen numerische Variablen sind, aber wenn Sie Bash 4 verwenden, ist es einfach, dies anzupassen, um assoziative Arrays mit den Abschnittsnamen selbst als Indizes zu verwenden.
Beachten Sie, dass Sie möglicherweise auch das von Khaled angezeigte Leerzeichen entfernen möchten (nur für $ 1 und Abschnitt), da Bash-Variablennamen keine Leerzeichen enthalten dürfen.
Diese Methode funktioniert auch nicht, wenn die Werte Gleichheitszeichen enthalten.
Eine andere Technik besteht darin, eine Bash-
while read
Schleife zu verwenden und die Zuweisungen auszuführen, während die Datei gelesen wird. Diesdeclare
ist vor den meisten schädlichen Inhalten sicher.Auch hier könnten assoziative Arrays recht einfach unterstützt werden.
quelle
Ich würde für diesen Job ein einfaches Python-Skript verwenden, da es den INI- Parser eingebaut hat :
und dann in bash:
Klar, es gibt kürzere Implementierungen in awk, aber ich denke, das ist lesbarer und leichter zu pflegen.
quelle
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Wenn Sie die zusätzlichen Leerzeichen entfernen möchten, können Sie die integrierte Funktion verwenden
gsub
. Sie können beispielsweise Folgendes hinzufügen:Dadurch werden alle Leerzeichen entfernt. Wenn Sie Leerzeichen am Anfang oder Ende des Tokens entfernen möchten, können Sie verwenden
quelle
Hier ist eine reine Bash-Lösung.
Dies ist eine neue und verbesserte Version dessen, was chilladx gepostet hat:
https://github.com/albfan/bash-ini-parser
Für eine wirklich einfache anfängliche Beispiel folgen: Wenn Sie diese herunterladen, kopieren Sie einfach die Dateien
bash-ini-parser
, undscripts/file.ini
in das gleiche Verzeichnis, dann ein Client - Testskript das Beispiel erstellen mit I unten als auch nach dem gleichen Verzeichnis zur Verfügung gestellt haben.Hier sind einige weitere Verbesserungen, die ich am Bash-Ini-Parser-Skript vorgenommen habe ...
Wenn Sie ini-Dateien mit Windows-Zeilenenden sowie mit Unix lesen möchten, fügen Sie diese Zeile der Funktion cfg_parser unmittelbar nach derjenigen hinzu, die die Datei liest:
Wenn Sie Dateien mit eingeschränkten Zugriffsberechtigungen lesen möchten, fügen Sie diese optionale Funktion hinzu:
quelle
chmod 777
. Während es sich bestenfalls um eine zwielichtige Übung handelt, ist es sicherlich nicht erforderlich, die INI-Datei ausführbar zu machen. Ein besserer Ansatz wäre,sudo
die Datei zu lesen und nicht mit den Berechtigungen herumzuspielen.Unter der Voraussetzung, dass Pythons ConfigParser verfügbar ist, kann man eine Shell-Hilfsfunktion wie die folgende erstellen:
$IFACE
und$param
sind der Abschnitt bzw. der Parameter.Dieser Helfer erlaubt dann Anrufe wie:
Hoffe das hilft!
quelle
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
… 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.
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:
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 .
Mit dieser
--type
Option können Sie bestimmte Einstellungen als Ganzzahlen, Boolesche Werte oder Pfade "kanonisieren" (automatisch erweitern~
):Etwas robusteres Quick-and-Dirty-Beispiel
Stellen Sie alle Variablen in
mytool.ini
wieSECTIONNAME_VARIABLENAME
in der aktuellen Umgebung zur Verfügung, und behalten Sie dabei das interne Leerzeichen in den Schlüsselwerten bei:Was der sed-Ausdruck auf Englisch tut, ist
\1
dann\2
, und\3
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:
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:
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:quelle