Tengo un script de instalación compatible con POSIX que determina la última versión de algún software recopilando información de un blob json recuperado de un 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": ,')
Necesito hacer que este software sea compatible con BusyBox, que, al igual que BSD grep, utiliza -E
soporte extendido para expresiones regulares. Sin embargo, no admite --version
banderas.
Si ejecuto busybox grep
veo la versión de Busybox. ¿Debería usar eso para agregar compatibilidad? ¿Existe una mejor manera de hacer esto para eliminar el olor del código sin instalar dependencias?
Respuesta1
No podía esperar más, así que puse algunos ojos nuevos en esto y se me ocurrió la siguiente solución que funcionó bien usando GNU, BSD y BusyBox grep, y mejora el soporte para semver:
egrep -o "\"version\".*[^,]*," <<< "$meta" | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" '
Funciona llamando a ERE grep conuna expresión regular(con unpunta del sombrero) y se utiliza cut
para cortar la coma final, tomar todo lo que está en el lado derecho de :
, recortar la cadena y eliminar las comillas dobles presentes.
Dado $meta
que {"version":"5.5.0-beta4",}
volverá exactamente 5.5.0-beta4
.
Dado $meta
que "version" : 1,
volverá exactamente 1
.
Se supone que version
el campo no es el último campo en el blob JSON, lo cual es una compensación por la legibilidad.
Aplicado a la pregunta original da como resultado:
vers=$(echo "$meta" | egrep -o "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
Eliminando la necesidad de detectar la versión de grep y eliminando el olor del código.
ACTUALIZAR:
Finalmente me llevaron a unsolución más eleganteusando sed
en unsiguiente preguntaen lo.