如果我想从字符串中删除第一个句点及其后面的所有内容,请sed
做:
echo 2.6.0.3-8 | sed 's/\..*//'
输出:
2
但如果我想删除第二个时期及其背后的一切,我想我应该能够这样做(GNU sed):
echo 2.6.0.3-8 | sed 's/\..*//2g'
然而输出是:
2.6.0.3-8
从手册:
' NUMBER' 仅替换REGEXP的第NUMBER个匹配。
我在这里错过了什么?
答案 0 :(得分:2)
这是因为表达是贪婪的。第一场比赛消耗.6.0.3-8
,第二场比赛没有留下任何文字。
你的正则表达式必须更准确
$ sed -E 's/([^.]+(\.[^.]+){3}).*/\1/' <<<"2.6.0.3-8"
2.6.0.3-8
$ sed -E 's/([^.]+(\.[^.]+){2}).*/\1/' <<<"2.6.0.3-8"
2.6.0
$ sed -E 's/([^.]+(\.[^.]+){1}).*/\1/' <<<"2.6.0.3-8"
2.6
$ sed -E 's/([^.]+(\.[^.]+){0}).*/\1/' <<<"2.6.0.3-8"
2
答案 1 :(得分:2)
你在那里但被.*
焚烧和贪婪。您需要针对特定情况执行的操作是将.*
替换为[^.]*
:
$ echo 2.6.0.3-8 | sed 's/\.[^.]*//2g' 2.6 $ echo 2.6.0.3-8 | sed 's/\.[^.]*//3g' 2.6.0 $ echo 2.6.0.3-8 | sed 's/\.[^.]*//1g' 2
[^.]
表示所有不属于点的字符。
答案 2 :(得分:1)
正如@stevesliva和@glennjackman所指出的,这里的问题是正则表达式匹配整行,因此 没有第二个匹配。
似乎没有通用的方法来实现仅使用正则表达式的替换。因此,删除第二个句点及其背后的所有内容的通用替代方法是使用P
和d
,例如:
echo 2.6.0.3-8 | sed 's/\./\n/2; P; d'
或便携式:
echo 2.6.0.3-8 | sed -e $'s/\\./\\\n/2' -e P -e d
两种情况下的输出:
2.6