J'essaie de convertir un fichier ini en variables de tableau bash. L'échantillon ini est comme ci-dessous:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
alors ceux-ci deviennent:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
etc.
En ce moment, je ne pouvais trouver que cette commande
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
En outre, un autre problème est qu'il ne prend pas en compte les espaces =
. Je pense que sed
c'est probablement mieux adapté pour ce travail, mais je ne sais pas comment conserver et stocker une variable temporaire pour le nom de la section dans sed
.
Alors une idée de comment faire ça?
ini
analyseur dansbash
.Réponses:
Gawk accepte les expressions régulières comme délimiteurs de champ. Ce qui suit élimine les espaces autour du signe égal, mais les conserve dans le reste de la ligne. Des guillemets sont ajoutés autour de la valeur afin que ces espaces, le cas échéant, soient préservés lorsque l'affectation Bash est effectuée. Je suppose que les noms de section seront des variables numériques, mais si vous utilisez Bash 4, il serait facile de l'adapter pour utiliser des tableaux associatifs avec les noms de section eux-mêmes comme indices.
Notez que vous pouvez également effectuer la suppression d'espace que Khaled affiche (sur seulement $ 1 et section) car les noms de variables Bash ne peuvent pas contenir d'espaces.
De plus, cette méthode ne fonctionnera pas si les valeurs contiennent des signes égaux.
Une autre technique consisterait à utiliser une
while read
boucle Bash et à effectuer les affectations pendant la lecture du fichier, en utilisantdeclare
ce qui est à l'abri de la plupart des contenus malveillants.Encore une fois, les tableaux associatifs pourraient assez facilement être pris en charge.
la source
J'utiliserais un script python simple pour ce travail car il a intégré l' analyseur INI :
puis en bash:
Bien sûr, il y a des implémentations plus courtes dans awk, mais je pense que c'est plus lisible et plus facile à maintenir.
la source
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Si vous souhaitez éliminer les espaces supplémentaires, vous pouvez utiliser la fonction intégrée
gsub
. Par exemple, vous pouvez ajouter:Cela supprimera tous les espaces. Si vous souhaitez supprimer des espaces au début ou à la fin du jeton, vous pouvez utiliser
la source
Voici une solution bash pure.
Il s'agit d'une nouvelle version améliorée de ce que chilladx a publié:
https://github.com/albfan/bash-ini-parser
Pour un exemple initial très facile à suivre: Après avoir téléchargé ceci, copiez simplement les fichiers
bash-ini-parser
etscripts/file.ini
dans le même répertoire, puis créez un script de test client en utilisant l'exemple que j'ai fourni ci-dessous dans ce même répertoire également.Voici quelques autres améliorations que j'ai apportées au script bash-ini-parser ...
Si vous voulez pouvoir lire les fichiers ini avec les fins de ligne Windows ainsi que Unix, ajoutez cette ligne à la fonction cfg_parser immédiatement après celle qui lit le fichier:
Si vous souhaitez lire des fichiers qui ont des autorisations d'accès restrictives, ajoutez cette fonction facultative:
la source
chmod 777
. Bien qu'une pratique louches au mieux, il n'est sûrement pas nécessaire de rendre le fichier ini exécutable. Une meilleure approche serait d'utilisersudo
pour lire le fichier, et non pour jouer avec les autorisations.En supposant toujours d'avoir ConfigParser de Python autour, on peut construire une fonction d'assistance shell comme ceci:
$IFACE
et$param
sont la section respectivement le paramètre.Cet assistant permet ensuite des appels comme:
J'espère que cela t'aides!
la source
Si Git est disponible et que vous êtes d'accord avec la contrainte de ne pas pouvoir utiliser de soulignements dans les noms de clés, vous pouvez l'utiliser
git config
comme analyseur / éditeur INI à usage général.Il gérera l'analyse de la paire clé / valeur de partout dans le
=
et supprimera les espaces insignifiants, plus vous obtiendrez des commentaires (les deux;
et#
) et tapez la contrainte essentiellement gratuitement. J'ai inclus un exemple de travail complet pour l'entrée de l'OP.ini
et la sortie souhaitée (tableaux associatifs Bash), ci-dessous.Cependant, étant donné un fichier de configuration comme celui-ci
… À condition que vous ayez juste besoin d'une solution rapide et sale, et que vous ne soyez pas marié avec l'idée d'avoir les paramètres dans un tableau associatif Bash, vous pouvez vous en sortir avec aussi peu que:
qui crée des variables d'environnement nommées
sectionname_variablename
dans l'environnement actuel. Cela, bien sûr, ne fonctionne que si vous pouvez être sûr qu'aucune de vos valeurs ne contiendra un point ou un espace (voir ci-dessous pour une solution plus robuste).Autres exemples simples
Récupération de valeurs arbitraires, à l'aide d'une fonction shell pour enregistrer la saisie:
Un alias serait OK, ici aussi, mais ceux-ci ne sont normalement pas développés dans un script shell [ 1 ], et de toute façon les alias sont remplacés par des fonctions shell "pour presque tous les usages", [ 2 ], selon la page de manuel Bash .
Avec cette
--type
option, vous pouvez "canoniser" des paramètres spécifiques sous forme d'entiers, de booléens ou de chemins (à expansion automatique~
):Exemple rapide et sale légèrement plus robuste
Rendre toutes les variables
mytool.ini
disponibles commeSECTIONNAME_VARIABLENAME
dans l'environnement actuel, en préservant les espaces internes dans les valeurs clés:Ce que fait l'expression sed, en anglais, c'est
\1
, puis\2
, et\3
Les séquences
\U
et\E
dans la chaîne de remplacement (qui majuscule cette partie de la chaîne de remplacement) sont unesed
extension GNU . Sur macOS et BSD, vous utiliseriez simplement plusieurs-e
expressions pour obtenir le même effet.Traiter les guillemets intégrés et les espaces dans les noms de section (ce qui
git config
permet) est laissé comme exercice pour le lecteur.:)
Utilisation de noms de section comme clés dans un tableau associatif Bash
Donné:
Cela produira le résultat demandé par l'OP, simplement en réorganisant certaines des captures dans l'expression de remplacement sed, et fonctionnera bien sans GNU sed:
Je prédis qu'il pourrait y avoir quelques défis avec la citation d'un
.ini
fichier réel , mais cela fonctionne pour l'exemple fourni. Résultat:la source