Use um analisador parecido como perl 's Config::Properties módulo. Eu faria o script inteiro em perl , mas se você tivesse que usar bash , você poderia fazer algo como:
typeset -A props
while IFS= read -rd '' key && IFS= read -rd '' value; do
props[$key]=$value
done < <(
perl -MConfig::Properties -l0 -e '
$p = Config::Properties->new();
$p->load(STDIN);
print for $p->properties' < file.properties
)
(também funciona com zsh ).
A implementação de um analisador completo em bash seria muito trabalhoso e significaria reinventar a roda. Você pode implementar um bom subconjunto com um loop while read simples, já que o read embutido espera um formato de entrada muito semelhante a esses arquivos de propriedades:
typeset -A props
while IFS=$':= \t' read key value; do
[[ $key = [#!]* ]] || [[ $key = "" ]] || props[$key]=$value
done < file.properties
(também funciona com ksh93 e zsh , os outros dois shell parecidos com o Bourne suportando matrizes associativas).
Isso lida com:
-
prop = value -
prop: value -
prop value - comentários no início da linha (
!e#com espaços em branco à esquerda opcionais) - escape de barra invertida (como em
foo\:\:bar=valuepara chaves que contêm delimitadores oufoo=\ baroupassword_with\backslash-and=equalsem sua amostra). - continuação de linha com barra invertida
No entanto, se verificarmos a especificação
- Isso não processa
\n,\r,\uXXXX... sequências - O LF é o único delimitador de linha reconhecido (não CR nem CRLF).
- O FF não é reconhecido como um espaço em branco (não podemos simplesmente adicioná-lo a
$IFS, porque\fnão é um caractere de espaço em branco IFS). - para uma entrada como
foo: bar =, que armazenabarem${props[foo]}em vez debar =(foo: bar:baz:está OK embora). Isso é apenas um problema quando o valor da propriedade contém um (sem escape) delimitador (:opcionalmente cercado por caracteres SPC / TAB,=opcionalmente cercado por caracteres SPC / TAB ou seqüência de um ou mais caracteres SPC / TAB) e é no final. - trata como linhas de comentários que começam com
\!ou\#. Somente um problema para propriedades cujo nome começa com!ou#. -
em
prop=1\ 2\ 3obtemos
1 2 3em vez de123: os espaços iniciais não são ignorados nas linhas de continuação como deveriam ser.