我需要做的就是从以下文件中提取版本信息:
my_archive_1.1.1.201_x86_64.tgz
我正在尝试提取版本号1.1.1
和版本号201
。通常我将 python 用于这些目的,但有人要求我不要这样做。我如何只使用 bash 来做到这一点?文件名将始终采用以下形式
([A-Za-z_]+)_([0-9]+\.[0-9]+\.[0-9]+)\.([0-9]+)_x86_64\.tgz
这些组在括号中。如果你从 1 开始数,我需要第二组和第三组。
使用纯 BASH:
s='my_archive_1.1.1.201_x86_64.tgz'
[[ $s =~ ^[^_]+_[^_]+_(([^.]+\.){2}[^.]+)\.([^_]+) ]] && \
echo "${BASH_REMATCH[1]}, ${BASH_REMATCH[3]}"
输出:
1.1.1, 201
使用您自己的正则表达式:
[[ $s =~ ([A-Za-z_]+)_([0-9]+\.[0-9]+\.[0-9]+).([0-9]+)_x86_64\.tgz ]] && \
echo "${BASH_REMATCH[2]}, ${BASH_REMATCH[3]}"
您可以使用简单的字符串替换来提取子字符串。你真的不需要正则表达式。作为奖励,这可以移植到其他 POSIX shell。这是否更简单是一个品味问题,也取决于问题。
s='my_archive_1.1.1.201_x86_64.tgz'
# ${s%%_[0-9]*} is 'my-archive'
s=${s#${s%%_[0-9]*}_}
# s='1.1.1.201_x86_64.tgz'
s=${s%%_*}
# s='1.1.1.201'
release=${s##*.}
version=${s%."$release"}
您可能还想尝试set
:
s='my_archive_1.1.1.201_x86_64.tgz'
oldIFS=$IFS
IFS=_
set $s
# $1 = my, $2=archive, $3=1.1.1.201, $4=x86, $5=64.tgz
# Shift until $1 contains only numbers and periods
while $1; do
case $1 in *[!.0-9]* ) shift ;; *) break ;; esac
done
IFS=.
set $1
version=$1.$2.$3
release=$4
IFS=$oldIFS
不使用正则表达式的另一种选择:
split=`echo "my_archive_1.1.1.201_x86_64.tgz" | cut -d'_' -f3`
versionnumber=`echo $split | cut -d'.' -f1,2,3`
releasenumber=`echo $split | cut -d'.' -f4`
echo "$versionnumber $releasenumber"