如何编写跨平台无依赖的Makefile指令实现从字符串中提取版本号
跨平台提取版本号的Makefile指令实现
原代码失效原因
- 带
-P参数的grep写法:-P是GNU grep专属的Perl正则扩展参数,macOS自带的BSD grep不支持该参数,因此无法运行。 - sed写法:一是
\d不属于POSIX标准正则的元字符,跨平台场景下需要替换为[0-9]或[[:digit:]];二是默认正则模式下+作为普通字符解析,同时GNU sed与BSD sed的扩展正则参数不一致,直接写会出现兼容性问题。
可用跨平台方案
方案1:POSIX兼容sed写法(推荐,无额外依赖全平台通用)
该写法完全符合POSIX标准,无需任何扩展参数,Linux的GNU sed与macOS的BSD sed都可正常运行:
echo "golangci-lint has version 1.42.0 built..." | sed -n 's/.*\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\).*/\1/p'
输出结果:1.42.0
Makefile中使用注意事项
Makefile中$符号需要转义,因此写入Makefile时要将\1改为\$$1,示例:
extract_version: @echo "golangci-lint has version 1.42.0 built..." | sed -n 's/.*\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\).*/\$$1/p'
方案2:awk实现
同样全平台通用,写法更简洁:
echo "golangci-lint has version 1.42.0 built..." | awk '{if(match($0, /[0-9]+\.[0-9]+\.[0-9]+/)) print substr($0, RSTART, RLENGTH)}'
内容的提问来源于stack exchange,提问作者ogbofjnr
相关产品推荐
相关产品推荐

