Eu tenho um script de instalação compatível com POSIX que determina a versão mais recente de algum software coletando informações de um blob json recuperado de um registro de software:
meta=$(wget -qO - https://registry.npmjs.org/after-dark/latest)
grep --version | grep "BSD grep" 1>/dev/null && vers=$(echo "$meta" | grep -oE '"version":(\d*?,|.*?[^\\]",)' | tr -d 'version": ,')
grep --version | grep "GNU grep" 1>/dev/null && vers=$(echo "$meta" | grep -oP '"version":(\d*?,|.*?[^\\]",)' | tr -d 'version": ,')
Preciso tornar este software compatível com o BusyBox, que, como o BSD grep, usa -E
para suporte estendido a regex. No entanto, não suporta --version
bandeira.
Se eu executar, busybox grep
vejo a versão do busybox. Devo usar isso apenas para adicionar compatibilidade? Existe uma maneira melhor de fazer isso para remover o cheiro de código sem instalar dependências.
Responder1
Não pude esperar mais, então olhei novamente para isso e criei a seguinte solução que testou bem usando GNU, BSD e BusyBox grep, e melhora o suporte para semver:
egrep -o "\"version\".*[^,]*," <<< "$meta" | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" '
Funciona chamando ERE grep comuma expressão regular(com umgorjeta de chapéu) e usa cut
para cortar a vírgula final, pegar tudo no lado direito do :
, cortar a string e remover quaisquer aspas duplas presentes.
Dado $meta
de {"version":"5.5.0-beta4",}
retornará exatamente 5.5.0-beta4
.
Dado $meta
de "version" : 1,
retornará exatamente 1
.
Assume que version
o campo não é o último campo no blob JSON, o que é uma compensação pela legibilidade.
Aplicado à pergunta original resulta em:
vers=$(echo "$meta" | egrep -o "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
Eliminando a necessidade de detectar a versão do grep e removendo o cheiro do código.
ATUALIZAR:
Acabei sendo levado a umsolução mais eleganteusando sed
em umquestão a seguirem SO.