sed:忽略可能存在或可能不存在的子字符串

时间:2019-01-04 10:42:16

标签: regex sed

使用sed,我需要匹配并忽略可能存在或可能不存在的子字符串

想象一下我有这四个字符串,每个字符串都在单独的行上:

>package-1.22.3.src.tar.gz<
>package-1.22.4.src.tar.gz<
>package-1.23.tar.gz<
>package-1.23.1.tar.gz<

这是我尝试过的:

sed "s,.*>package-\(.[^<]*\)\(\.src\)\?\.tar.*<,\1,g"

我想要一个能输出以下内容的sed正则表达式:

1.22.3
1.22.4
1.23
1.23.1

但是我知道

1.22.3.src
1.22.4.src
1.23
1.23.1

2 个答案:

答案 0 :(得分:1)

.[^<]*模式匹配带有.的任何字符,然后[^<]*匹配<之外的任何0+字符。它与.src部分匹配,因此可选\(\.src\)\?不需要匹配,并且.src落入组1。

如果要修复当前代码,只需将package-后的数字和点与[0-9.]*匹配:

sed "s,.*>package-\([0-9.]*\)\(\.src\)\?\.tar.*<,\1,g"
                    ^^^^^^^ 

请参见online demo

如果您有GNU grep,则也可以使用PCRE模式,例如

grep -oP ">package-\K\d+(\.\d+)+"

请参见another online demo。在此,匹配>package-之后,使用\K运算符将文本从匹配中删除,然后匹配1+位数字,然后重复1个或多个.,然后匹配并返回1+位数字-o选项的帮助。

答案 1 :(得分:0)

sed应该有效:

sed -E -n 's/.*-(.*\.[0-9]+).*<$/\1/p'

输出:

1.22.3
1.22.4
1.23
1.23.1