在Bash中使用正则表达式提取版本号

3

我只需要从以下文件中提取版本信息:

 my_archive_1.1.1.201_x86_64.tgz

我正在尝试提取版本号和发布号,版本号是1.1.1,发布号是201。通常我使用Python来完成这些任务,但被要求不使用Python。如何只使用bash实现呢?文件名的格式始终为

([A-Za-z_]+)_([0-9]+\.[0-9]+\.[0-9]+)\.([0-9]+)_x86_64\.tgz

组在括号中。如果从1开始计数,则需要第二组和第三组。
3个回答

7

纯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]}"

2

您可以使用简单的字符串替换来提取子字符串。您并不真正需要正则表达式。作为奖励,这在其他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

1

如果不使用正则表达式,还有另一种选择:

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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接