#!/bin/bash # -*-tab-width:4-*- die() { echo $1 >&2 exit 1 } _version_parse_range() { [[ $1 =~ ^([0-9]+)(-([0-9]*))?$ ]] || die "Bad range syntax: \"$1\"" start=${BASH_REMATCH[1]} [[ ${BASH_REMATCH[2]} ]] && end=${BASH_REMATCH[3]} || end=${start} [[ ${start} -gt 0 ]] && [[ -z ${end} || ${start} -le ${end} ]] \ || die "Bad range: \"$1\"" } _version_split() { local v=$1 LC_ALL=C # get first component [[ ${v} =~ ^([A-Za-z]*|[0-9]*) ]] || die "No match" comp=("${BASH_REMATCH[1]}") v=${v:${#BASH_REMATCH[0]}} # get remaining separators and components while [[ ${v} ]]; do [[ ${v} =~ ^([^A-Za-z0-9]*)([A-Za-z]*|[0-9]*) ]] || die "No match" comp+=("${BASH_REMATCH[@]:1:2}") v=${v:${#BASH_REMATCH[0]}} done } version_cut() { local start end local -a comp _version_parse_range "$1" _version_split "${2-${PV}}" local IFS= if [[ ${end} ]]; then echo "${comp[*]:(start-1)*2:(end-start)*2+1}" else echo "${comp[*]:(start-1)*2}" fi } version_rs() { local start end i local -a comp (( $# & 1 )) && _version_split "${@: -1}" || _version_split "${PV}" while [[ $# -ge 2 ]]; do _version_parse_range "$1" [[ ${end} && ${end} -le $((${#comp[@]}/2)) ]] || end=$((${#comp[@]}/2)) for (( i = start*2 - 1; i < end*2; i+=2 )); do comp[i]=$2 done shift 2 done local IFS= echo "${comp[*]}" }