使用bash中的正则表达式提取版本

时间:2013-08-12 07:07:35

标签: regex bash

我需要做的就是从以下文件中提取版本控制信息:

 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开始计数,我需要第二组和第三组。

3 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:2)

您可以使用简单的字符串替换来提取子字符串。你真的不需要正则表达式。作为奖励,这可以移植到其他POSIX外壳。这是否更简单是一个品味问题,也取决于问题。

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

答案 2 :(得分:0)

另一种不使用正则表达式的替代方法:

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"