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 configcome 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 .inie 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_variablenamenell'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' --typeopzione, 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.inicome SECTIONNAME_VARIABLENAMEnell'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
\1allora
- 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 \Ue \Enella stringa di sostituzione (che in maiuscolo quella parte della stringa di sostituzione) sono l' sedestensione GNU . Su macOS e BSD, useresti solo -eespressioni multiple per ottenere lo stesso effetto.
Trattare con virgolette incorporate e spazi bianchi nei nomi delle sezioni (che git configconsente) 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 .inifile 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" )