bash 正则表达式匹配语义版本号
Posted
技术标签:
【中文标题】bash 正则表达式匹配语义版本号【英文标题】:bash regex to match semantic version number 【发布时间】:2014-08-10 17:15:36 【问题描述】:我有以下几点:
versionNumber=$(sw_vers -productVersion) # Finds version number
versionShort=$versionNumber:0:4 # Cut string to 1 decimal place for calculation
当版本如下时有效:
10.9.2
10.9.5
但它不会匹配
10.10.3
因为它只会返回
10.1
但我希望将 versionShort 设置为
10.10
我想匹配上面的主要版本,第一个点和次要版本。
【问题讨论】:
【参考方案1】:无正则表达式解决方案 - 切断最后一个点及其后面的任何内容:
versionShort=$versionNumber%.*
【讨论】:
【参考方案2】:正则表达式解决方案:
[[ $versionNumber =~ ^[0-9]+\.[0-9]+ ]] && echo "$BASH_REMATCH[0]"
它总是会打印前两个数字,例如所有这些:
10.5
10.5.9
10.5.8.2
将导致10.5
输出。您还可以添加一个else
子句来检查是否发生了错误(未找到匹配项)。
这是一个更长的版本:
if [[ $versionNumber =~ ^[0-9]+\.[0-9]+ ]]; then
versionShort=$BASH_REMATCH[0]
else
echo "Something is wrong with your version" >&2
fi
【讨论】:
如何将结果返回给变量? @lukemh 我添加了一个更长的版本,可能对你来说更清楚。如果它不起作用...您确定您使用的是 bash 吗?如果是,那么是哪个版本?在版本 3 中,您必须将条件表达式的右侧放入变量中。 semantic version 标签必须正好有 3 个数字。 @MikeSamuel 是的,没错。随意编辑答案。我希望完全删除它更容易,但提及BASH_REMATCH
是一个值得的目标,即使是这样的错误答案。
……或者你自己写,我会删除我的:)【参考方案3】:
我有一个类似的问题,但我需要访问所有 3 个部分。我做了一些研究和测试,发现这个效果很好
product_version=$(sw_vers -productVersion)
semver=( $product_version//./ )
major="$semver[0]"
minor="$semver[1]"
patch="$semver[2]"
echo "$major.$minor.$patch"
要直接回答这个问题,你可以
product_version=$(sw_vers -productVersion)
semver=( $product_version//./ )
major="$semver[0]"
minor="$semver[1]"
patch="$semver[2]"
versionShort="$major.$minor"
或者你可以使用更少的变量
product_version=$(sw_vers -productVersion)
semver=( $product_version//./ )
versionShort="$semver[0].$semver[1]"
【讨论】:
“semver=( $product_version//./ )”如何工作?不幸的是,当我尝试这个时,我得到了 semver="10.11.6//./"。 @JasonHarrison 代码通过替换点“。”来工作。用空格“”,然后将所有参数作为 bash 数组。为了使其工作,您需要首先将 semver 文本分配给一个变量。例如,a="10.11.6"; semver=( $a//./ )
【参考方案4】:
https://github.com/fsaintjacques/semver-tool https://github.com/fsaintjacques/semver-tool/blob/master/src/semver
SEMVER_REGEX="^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
function validate-version
local version=$1
if [[ "$version" =~ $SEMVER_REGEX ]]; then
# if a second argument is passed, store the result in var named by $2
if [ "$#" -eq "2" ]; then
local major=$BASH_REMATCH[1]
local minor=$BASH_REMATCH[2]
local patch=$BASH_REMATCH[3]
local prere=$BASH_REMATCH[4]
local build=$BASH_REMATCH[5]
eval "$2=(\"$major\" \"$minor\" \"$patch\" \"$prere\" \"$build\")"
else
echo "$version"
fi
else
error "version $version does not match the semver scheme 'X.Y.Z(-PRERELEASE)(+BUILD)'. See help for more information."
fi
【讨论】:
注意:这个 sn-p 包含根据 GNU GPL v3 许可的代码:github.com/fsaintjacques/semver-tool/blob/master/LICENSE以上是关于bash 正则表达式匹配语义版本号的主要内容,如果未能解决你的问题,请参考以下文章
spring cloud: zuul: 正则表达式匹配其他微服务(给其他微服务加版本号)