替换第 n 个正则表达式问题



如果我想从字符串中删除第一个句点及其后面的所有内容,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 所指出的,这里的问题是正则表达式与整行匹配,因此没有第二个匹配项。

似乎没有一种通用的方法来实现仅正则表达式的替换。因此,删除第二个周期及其后面的所有内容的通用替代方案是使用Pd,例如:

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

最新更新