#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