如何使用 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.56 或 4.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:](]*\).*//'
但是就像每次提取一样,您需要定义您想要的,而不是可能存在的并提取它(或更改您的请求)。
我在 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.56 或 4.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:](]*\).*//'
但是就像每次提取一样,您需要定义您想要的,而不是可能存在的并提取它(或更改您的请求)。