регулярное выражение bash для соответствия семантическому номеру версии

#regex #bash #semantic-versioning

#регулярное выражение #bash #семантическое управление версиями

Вопрос:

У меня есть следующее:

 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%.*}
  

Комментарии:

1. Осторожно, это не работает при использовании версий semver с суффиксом предварительной версии, например 10.9.5-rc.1

Ответ №2:

Решение для регулярных выражений:

 [[ $versionNumber =~ ^[0-9] .[0-9]  ]] amp;amp; 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" >amp;2
fi
  

Комментарии:

1. как мне вернуть результат в переменную?

2. @lukemh Я добавил более длинную версию, которая может быть понятнее для вас. Если это не работает … вы уверены, что используете bash? Если да, то какая версия? В версии 3 вы должны поместить правую часть условного выражения в переменную.

3. теги семантической версии должны содержать ровно 3 номера.

4. @MikeSamuel да, это верно. Не стесняйтесь редактировать ответ. Хотелось бы, чтобы его было проще полностью удалить, но упоминание BASH_REMATCH — достойная цель, даже при таком плохом ответе.

5. … или напишите свое собственное, и я удалю свое 🙂

Ответ №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]}"
  

Комментарии:

1. Как работает «semver=( $ {product_version//./} )»? К сожалению, я получаю semver=»10.11.6//./» когда я пытаюсь это сделать.

2. @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
}  

Комментарии:

1. Примечание: этот фрагмент содержит код, который лицензирован по GNU GPL v3: github.com/fsaintjacques/semver-tool/blob/master/LICENSE