如何使用 sed 提取复杂的版本号?

How to extract a complex version number using sed?

我在 CentOs 中使用 sed 提取版本号,它工作正常:

echo "var/opt/test/war/test-webapp-4.1.56.war" | sed -nre 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*//p'

但我的问题是,当版本显示如下时,我无法提取:

var/opt/test/war/test-webapp-4.1.56-RC1.war

如果 4.1.56-RC1 存在,我想提取它。

有什么想法吗?

编辑 2

好的,以这个例子为例,路径为:

有时路径只包含这样的序号 var/opt/test/war/test-webapp-4.1.56.war 有时它包含一串数字和字母像这样“var/opt/test/war/test-webapp-4.1.56-RC1.war

需要根据路径中存在的版本恢复 4.1.564.1.56-RC1。使用 sed 或 grep,没有偏好。

这似乎可行,但 .war 显示在末尾:

echo "var/opt/test/war/test-webapp-4.1.56.war" | egrep -o '[0-9]\S*'

那样只使用空格作为分隔符怎么样?
echo "Version 4.2.4-RC1 (test version)" | grep -Po "Version\s+\K\S+"

for grep -P 表示使用 Perl 样式正则表达式,-o 仅显示匹配部分,字符串中的 \K 表示不显示它之前的所有内容作为比赛

只需将 (-[a-zA-Z]+[0-9]+) 添加到您的正则表达式中:

echo "Version 4.2.4 (test version)" | sed -nre 's/^[^0-9]*(([0-9]+\.)*[0-9]+(-[a-zA-Z]+[0-9]+)).*//p'

有点不清楚你在追求什么,但这似乎是大方向。

鉴于:

$ echo "$e"
/var/opt/test/war/test-webapp-4.1.56-RC1.war
/var/opt/test/war/test-webapp-RC1.war
Version 4.2.4 (test version)

尝试:

$ echo "$e" | egrep -o '(\d+\.\d+\.\d+-?\w*)'
4.1.56-RC1
4.2.4

这两个测试都通过了

egrep -o '[0-9]\S*'

不幸的是,并非所有 grep 都支持 -o,但 Linux 中的 grep 支持。

以下将匹配长度最多为 2 位的第一个数字({1,2},第二个最多 2 个数字,最后最多 4 个数字,后跟任何非 space 最多space.

grep -o '[0-9]\{1,2\}.[0-9]\{1,2\}.[0-9]\{1,4\}' 
echo "Version 4.2.4 (test version)" | sed 's/Version[[:space:]]*\([^[:space:](]*\).*//'

但是就像每次提取一样,您需要定义您想要的,而不是可能存在的并提取它(或更改您的请求)。