У меня есть POSIX-совместимый установочный скрипт, который определяет последнюю версию некоторого программного обеспечения, извлекая информацию из двоичного двоичного объекта JSON, извлеченного из реестра программного обеспечения:
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": ,')
Мне нужно сделать это программное обеспечение совместимым с BusyBox, который, как и BSD grep, использует -E
для расширенной поддержки регулярных выражений. Однако он не поддерживает --version
флаг.
Если я запускаю, busybox grep
то вижу версию busybox. Мне просто использовать это, чтобы добавить совместимости? Есть ли лучший способ, которым я мог бы сделать это, чтобы удалить запах кода без установки зависимостей.
решение1
Не в силах больше ждать, я бросил на это свежий взгляд и придумал следующее решение, которое хорошо зарекомендовало себя при использовании GNU, BSD и BusyBox grep, а также улучшило поддержку semver:
egrep -o "\"version\".*[^,]*," <<< "$meta" | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" '
Работает путем вызова ERE grep срегулярное выражение(сподсказка) и используется cut
для обрезки завершающей запятой, захвата всего, что находится справа от :
, обрезки строки и удаления всех имеющихся двойных кавычек.
Приведено $meta
из {"version":"5.5.0-beta4",}
вернётся точно 5.5.0-beta4
.
Приведено $meta
из "version" : 1,
вернётся точно 1
.
Предполагается, что version
поле не является последним полем в BLOB-объекте JSON, что является компромиссом для удобства чтения.
Применительно к исходному вопросу результаты следующие:
vers=$(echo "$meta" | egrep -o "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
Устранение необходимости определения версии grep и устранение запаха кода.
ОБНОВЛЯТЬ:
В конце концов меня привели кболее элегантное решениеиспользуя sed
вдополнительный вопросна SO.