Estou tentando converter um arquivo ini em variáveis de matriz bash. A amostra ini é como abaixo:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
então eles se tornam:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
e assim por diante.
No momento, eu poderia criar apenas esse comando
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Além disso, outro problema é que ele não leva =
em consideração os espaços próximos . Acho que sed
provavelmente é mais adequado para esse trabalho, mas não sei como armazenar e armazenar uma variável temporária para o nome da seção sed
.
Então, alguma idéia de como fazer isso?
ini
analisador embash
.Respostas:
Gawk aceita expressões regulares como delimitadores de campo. A seguir, elimina os espaços ao redor do sinal de igual, mas os preserva no restante da linha. As aspas são adicionadas em torno do valor para que esses espaços, se houver, sejam preservados quando a atribuição do Bash for executada. Estou assumindo que os nomes das seções serão variáveis numéricas, mas se você estiver usando o Bash 4, seria fácil adaptar isso para usar matrizes associativas com os próprios nomes das seções como índices.
Observe que você também pode fazer a remoção de espaço que Khaled mostra (em apenas US $ 1 e seção), pois os nomes de variáveis do Bash não podem conter espaços.
Além disso, esse método não funcionará se os valores contiverem sinais de igual.
Outra técnica seria usar um
while read
loop Bash e executar as atribuições à medida que o arquivo é lido, odeclare
que é seguro para a maioria dos conteúdos maliciosos.Novamente, matrizes associativas poderiam ser facilmente suportadas.
fonte
Eu usaria um script python simples para este trabalho, pois ele foi incorporado no analisador INI :
e depois no bash:
Claro, existem implementações mais curtas no awk, mas acho que isso é mais legível e mais fácil de manter.
fonte
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Se você deseja eliminar os espaços extras, pode usar a função interna
gsub
. Por exemplo, você pode adicionar:Isso removerá todos os espaços. Se você deseja remover espaços no início ou no final do token, pode usar
fonte
Aqui está uma solução pura para o bash.
Esta é uma versão nova e aprimorada do que chilladx postou:
https://github.com/albfan/bash-ini-parser
Para um exemplo inicial realmente fácil de seguir: Depois de fazer o download, copie os arquivos
bash-ini-parser
escripts/file.ini
para o mesmo diretório e crie um script de teste do cliente usando o exemplo que forneci abaixo para o mesmo diretório também.Aqui estão algumas outras melhorias que eu fiz no script bash-ini-parser ...
Se você quiser ler arquivos ini com finais de linha do Windows e Unix, adicione essa linha à função cfg_parser imediatamente após a que lê o arquivo:
Se você quiser ler arquivos com permissões de acesso restritivas, adicione esta função opcional:
fonte
chmod 777
. Enquanto uma prática obscura, na melhor das hipóteses, certamente não há necessidade de tornar o arquivo ini executável. Uma abordagem melhor seria usarsudo
para ler o arquivo, não mexer nas permissões.Sempre assumindo que o ConfigParser do Python esteja por perto, pode-se criar uma função auxiliar de shell como esta:
$IFACE
e$param
são a seção, respectivamente, o parâmetroEsse ajudante permite chamadas como:
Espero que isto ajude!
fonte
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
… 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:
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:
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 .
Com a
--type
opção, você pode "canonizar" configurações específicas como números inteiros, booleanos ou caminhos (expandindo automaticamente~
):Exemplo rápido e sujo um pouco mais robusto
Disponibilize todas as variáveis
mytool.ini
comoSECTIONNAME_VARIABLENAME
no ambiente atual, preservando o espaço em branco interno nos valores-chave:O que a expressão sed está fazendo, em inglês, é
\1
,\2
e\3
As seqüências
\U
e\E
na sequência de substituição (que maiúscula essa parte da sequência de substituição) sãosed
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:
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:
Prevejo que pode haver alguns desafios com a citação de um
.ini
arquivo do mundo real , mas funciona para o exemplo fornecido. Resultado:fonte