Se você tiver o Git disponível e estiver com a restrição de não poder usar sublinhados nos nomes das chaves, poderá usá-lo git config
como um analisador / editor INI de uso geral.
Ele manipulará a análise do par de chave / valor em torno do =
espaço em branco insignificante e descartará, além de obter comentários (ambos ;
e #
) e digitar coerção basicamente de graça. Incluí um exemplo de trabalho completo para a entrada do OP .ini
e a saída desejada (matrizes associativas Bash), abaixo.
No entanto, dado um arquivo de configuração como este
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
… Desde que você precise apenas de uma solução rápida e suja e não seja casado com a idéia de ter as configurações em uma matriz associativa do Bash, você pode se dar bem com o seguinte:
eval $(git config -f mytool.ini --list | tr . _)
# or if 'eval' skeeves you out excessively
source <(git config -f mytool.ini --list | tr . _)
que cria variáveis de ambiente nomeadas sectionname_variablename
no ambiente atual. Obviamente, isso só funciona se você puder confiar que nenhum dos seus valores conterá um período ou espaço em branco (veja abaixo uma solução mais robusta).
Outros exemplos simples
Buscando valores arbitrários, usando uma função shell para salvar a digitação:
function myini() { git config -f mytool.ini; }
Um alias também seria bom aqui, mas normalmente não é expandido em um script de shell [ 1 ], e de qualquer maneira os aliases são substituídos pelas funções de shell "para quase todos os fins" [ 2 ], de acordo com a página de manual do Bash .
myini --list
# result:
# section1.inputdir=~/some/dir
# section1.enablesomefeature=true
# section1.enablesomeotherfeature=yes
# section2.anothersetting=42
myini --get section1.inputdir
# result:
# ~/some/dir
Com a --type
opção, você pode "canonizar" configurações específicas como números inteiros, booleanos ou caminhos (expandindo 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
Exemplo rápido e sujo um pouco mais robusto
Disponibilize todas as variáveis mytool.ini
como SECTIONNAME_VARIABLENAME
no ambiente atual, preservando o espaço em branco interno nos valores-chave:
source <(
git config -f mytool.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/\U\1_\2\E="\3"/'
)
O que a expressão sed está fazendo, em inglês, é
- encontrar um monte de caracteres não menstruais até um período, lembrando que
\1
,
- encontrar um monte de caracteres até um sinal de igual, lembrando que como
\2
e
- localizando todos os caracteres após o sinal de igual como
\3
- finalmente, na cadeia de substituição
- o nome da seção + nome da variável está em maiúsculas e
- a parte do valor está entre aspas duplas, caso contenha caracteres que tenham um significado especial para o shell se não estiverem entre aspas (como espaço em branco)
As seqüências \U
e \E
na sequência de substituição (que maiúscula essa parte da sequência de substituição) são sed
extensão GNU . No macOS e no BSD, você usaria várias -e
expressões para obter o mesmo efeito.
Lidar com aspas incorporadas e espaços em branco nos nomes das seções (o que git config
permite) é deixado como um exercício para o leitor.:)
Usando nomes de seção como chaves em uma matriz associativa Bash
Dado:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
Isso produzirá o resultado solicitado pelo OP, simplesmente reorganizando algumas das capturas na expressão de substituição do sed e funcionará bem sem o GNU sed:
source <(
git config -f foo.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/declare -A \2["\1"]="\3"/'
)
Prevejo que pode haver alguns desafios com a citação de um .ini
arquivo do mundo real , mas funciona para o exemplo fornecido. Resultado:
declare -p {session,path}
# result:
# declare -A session=([barfoo]="bar" [foobar]="foo" )
# declare -A path=([barfoo]="/some/path" [foobar]="/some/path" )