【问题标题】:bash regex to match semantic version numberbash 正则表达式匹配语义版本号
【发布时间】: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

我想匹配上面的主要版本,第一个点和次要版本。

【问题讨论】:

    标签: regex bash semantic-versioning


    【解决方案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
      }

      【讨论】:

      猜你喜欢
      • 2018-04-17
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-22
      • 2013-09-13
      相关资源
      最近更新 更多