我有一个与 POSIX 兼容的安装脚本,它通过从软件注册表中检索到的 json blob 中 grepping 信息来确定某些软件的最新版本:
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
字段不是 JSON blob 中的最后一个字段,这是为了可读性而做出的权衡。
应用于原始问题的结果是:
vers=$(echo "$meta" | egrep -o "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
无需检测 grep 的版本,消除代码异味。
更新: