Se hai Git disponibile e stai bene con il vincolo di non poter usare i caratteri di sottolineatura nei nomi delle chiavi, puoi usare git config
come un parser / editor INI generico.
Gestirà l'analisi della coppia chiave / valore intorno allo =
spazio bianco scarto e scartato, oltre a ottenere commenti (entrambi ;
e #
) e digitare la coercizione praticamente gratuitamente. Di seguito ho incluso un esempio di lavoro completo per l'input dell'OP .ini
e l'output desiderato (array associativi di Bash).
Tuttavia, dato un file di configurazione come questo
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
... purché tu abbia solo bisogno di una soluzione rapida e sporca e non sei sposato con l'idea di avere le impostazioni in un array associativo Bash, potresti cavartela con un minimo di:
eval $(git config -f mytool.ini --list | tr . _)
# or if 'eval' skeeves you out excessively
source <(git config -f mytool.ini --list | tr . _)
che crea variabili di ambiente denominate sectionname_variablename
nell'ambiente corrente. Questo, ovviamente, funziona solo se puoi fidarti che nessuno dei tuoi valori conterrà mai un punto o uno spazio bianco (vedi sotto per una soluzione più solida).
Altri semplici esempi
Recupero di valori arbitrari, utilizzando una funzione shell per salvare la digitazione:
function myini() { git config -f mytool.ini; }
Un alias sarebbe OK, anche qui, ma quelli normalmente non sono espansi in uno script di shell [ 1 ], e comunque gli alias sono sostituiti dalle funzioni di shell "per quasi tutti gli scopi", [ 2 ], secondo la pagina man di Bash .
myini --list
# result:
# section1.inputdir=~/some/dir
# section1.enablesomefeature=true
# section1.enablesomeotherfeature=yes
# section2.anothersetting=42
myini --get section1.inputdir
# result:
# ~/some/dir
Con l' --type
opzione, puoi "canonicalizzare" impostazioni specifiche come numeri interi, valori booleani o percorsi (espandendosi automaticamente ~
):
myini --get --type=path section1.inputdir # value '~/some/dir'
# result:
# /home/myuser/some/dir
myini --get --type=bool section1.enablesomeotherfeature # value 'yes'
# result:
# true
Esempio di quick-and-dirty leggermente più robusto
Rendi disponibili tutte le variabili mytool.ini
come SECTIONNAME_VARIABLENAME
nell'ambiente corrente, preservando gli spazi bianchi interni nei valori chiave:
source <(
git config -f mytool.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/\U\1_\2\E="\3"/'
)
Quello che sta facendo l'espressione sed, in inglese, è
- trovare un gruppo di personaggi non periodici fino a un punto, ricordandolo come
\1
allora
- trovare un gruppo di caratteri fino a un segno di uguale, ricordandolo come
\2
, e
- trovare tutti i caratteri dopo il segno di uguale come
\3
- infine, nella stringa di sostituzione
- il nome della sezione + il nome della variabile è maiuscolo, e
- la parte del valore è racchiusa tra virgolette, nel caso contenga caratteri che hanno un significato speciale per la shell se non quotati (come gli spazi)
Le sequenze \U
e \E
nella stringa di sostituzione (che in maiuscolo quella parte della stringa di sostituzione) sono l' sed
estensione GNU . Su macOS e BSD, useresti solo -e
espressioni multiple per ottenere lo stesso effetto.
Trattare con virgolette incorporate e spazi bianchi nei nomi delle sezioni (che git config
consente) viene lasciato come esercizio per il lettore.:)
Utilizzo dei nomi delle sezioni come chiavi in un array associativo Bash
Dato:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
Ciò produrrà il risultato richiesto dall'OP, semplicemente riorganizzando alcune delle catture nell'espressione di sostituzione sed e funzionerà bene senza GNU sed:
source <(
git config -f foo.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/declare -A \2["\1"]="\3"/'
)
Prevedo che potrebbero esserci delle difficoltà con la citazione di un .ini
file del mondo reale , ma funziona per l'esempio fornito. Risultato:
declare -p {session,path}
# result:
# declare -A session=([barfoo]="bar" [foobar]="foo" )
# declare -A path=([barfoo]="/some/path" [foobar]="/some/path" )