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