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=value
para chaves que contêm delimitadores oufoo=\ bar
oupassword_with\backslash-and=equals
em 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\f
não é um caractere de espaço em branco IFS). - para uma entrada como
foo: bar =
, que armazenabar
em${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\ 3
obtemos
1 2 3
em vez de123
: os espaços iniciais não são ignorados nas linhas de continuação como deveriam ser.