如果我想从字符串中删除第一个句点及其后面的所有内容,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
从手册:
"数字" 仅替换正则表达式的第 NUMBERmatch。
我在这里错过了什么?
你在那里,但被.*
和贪婪烧伤了。 对于特定情况,您所要做的就是将.*
替换为[^.]*
:
$ echo 2.6.0.3-8 | sed 's/\.[^.]*//2克' 2.6 $ 回声 2.6.0.3-8 |sed 's/\.[^.]*//3克' 2.6.0 $ 回声 2.6.0.3-8 |sed 's/\.[^.]*//1克' 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
正如 @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