Você pode escrever de forma muito mais legível usando awk
:
getval() {
awk -F'=' '$1~/\<'"$1"'\>/{print $2}' testfile
}
Considere um arquivo com key=value
pares e cada key
é opcionalmente uma concatenação de vários key
s. Em outras palavras, muitos key
s podem mapear para um value
. A razão por trás disso é que cada key
é uma palavra relativamente curta em comparação com o comprimento do value
, portanto, os dados estão sendo 'compactados' em linhas menores.
Ilustração (ou seja, não os valores reais):
$ cat testfile
AA,BB,CC=a-lengthy-value
A,B,C=a-very-long-value
D,E,F=another-very-long-value
K1,K2,K3=many-many-more
Z=more-long-value
É válido assumir que todos os key
s são exclusivos e não conterão os seguintes caracteres:
key
delimiter: ,
=
key
s pode vir de qualquer forma no futuro (com as restrições acima), mas se ajudar, eles atualmente aderem ao seguinte regex coincidentemente: %código%. Da mesma forma, [[:upper:]]{2}[[:upper:]0-9]
s não conterá value
, portanto, =
pode ser usado com segurança para dividir cada linha. Não existem multi-linhas =
s ou key
s, portanto, também é seguro processar linha por linha.
Para facilitar a extração de dados desse arquivo, uma função value
é definida como:
getval() {
sed -n "/^\([^,]*,\)*$1\(,[^=]*\)*=\(.*\)$/{s///p;q}" testfile
}
Assim, chamar getval()
retornará o valor getval A
, não a-very-long-value
. Ele também não deve retornar nada para um a-lengthy-value
inexistente.
Perguntas:
key
é robusta o suficiente? Por que vale a pena, esse script será executado com getval()
e bash
do cygwin que vem com ele. A portabilidade não é necessária aqui como resultado (isto é, apenas pontos de brownie serão dados). Obrigado!
edit:
Função corrigida, esclarecimento adicional sobre as chaves.
edit 2:
Acrescentou esclarecimentos sobre o formato (sem multi-linhas) e portabilidade (não é um requisito).
com sed
...
getval() { sed "/^\([^=]*,\)*$1[,=]/!d;s/.*=//;q"; } <infile
Você pode querer validar $1
como entrada.
Ou com o GNU grep
e cut
:
getval() { grep -Em1 "^([^=]*,)*$1[,=]" | cut -d= -f2-; } <infile