发现很难使用sed从字符串中提取数字

时间:2019-10-17 09:30:51

标签: sed

我正在尝试使用sed如下提取字符串的版本信息

echo "A10.1.1-Vers8" | sed -n "s/^A\([0-9]+\)\.\([0-9]\)\.[0-9]+-.*/\1/p"

我想在“ A”之后提取“ 10”。但是上面的表达式没有给出预期的信息。有人可以解释一下为什么这个说法不起作用吗?

我尝试了上述命令,并更改了选项,但没有任何效果。我认为这是一些语法错误

echo "A10.1.1-Vers10" | sed -n "s/^X\([0-9]+\)\.\([0-9]\)\.[0-9]+-.*/\1/p"

预期结果为“ 10” 实际结果是无

2 个答案:

答案 0 :(得分:2)

$ echo "A10.1.1-Vers8" | sed -r 's/^A([[:digit:]]+)\.(.*)$/\1/g'
10

搜索以A(^A开头的字符串,然后搜索多个数字(我使用的是POSIX character class [[:digit:]]+),该字符串被捕获在()组中,然后是文字点\.,然后是其他所有(.*)$

最后,将整个内容替换为“捕获的组”内容\1

在GNU sed中,-r添加了一些语法糖,在手册页中将其称为--regexp-extended

答案 1 :(得分:1)

GNU grepsed的替代选择:

$ echo "A10.1.1-Vers10" | grep -oP '(?<=^A)[0-9]+'
10

-o选项告诉grep仅打印匹配的字符。

-P选项告诉grep匹配Perl正则表达式,这使(?<=成为零长度断言的后盾。

后置断言(?<=^A)确保行的开头有一个A,但不将其作为输出匹配的一部分。

如果您需要匹配更多的版本字符串,则可以使用前瞻性断言:

$ echo "A10.1.1-Vers10" | grep -oP '(?<=^A)[0-9]+(?=\.[0-9]+\.[0-9]+-.*)'
10