Sed递归替换

时间:2012-04-02 20:52:20

标签: regex sed

echo ddayaynightday | sed 's/day//g'

结束daynight

无论如何都要替换它直到不再匹配?

6 个答案:

答案 0 :(得分:18)

我喜欢的表格,对于这种情况:

echo ddayaynightday | sed -e ':loop' -e 's/day//g' -e 't loop'

这和其他人一样,除了它使用多个-e命令来制作三行并使用t构造 - 这意味着“分支,如果你做了一次成功的替换” - 迭代。 / p>

答案 1 :(得分:5)

这可能对您有用:

echo ddayaynightday | sed ':a;s/day//g;ta'
night

答案 2 :(得分:3)

g标志故意不与字符串的替换部分重新匹配。你需要做的是有点不同。试试这个:

echo ddayaynightday | sed $':begin\n/day/{ s///; bbegin\n}'

由于BSD Sed的怪癖,需要嵌入的换行符。如果您正在使用GNU Sed,您可以使用

sed ':begin;/day/{ s///; bbegin }'

答案 3 :(得分:2)

以下作品:

$ echo ddayaynightday | sed ':loop;/day/{s///g;b loop}'
night

根据您的系统,;可能无法分离命令,因此您可以使用以下代码:

echo ddayaynightday | sed -e ':loop' -e '/day/{s///g
                                               b loop}'

说明:

:loop       # Create the label 'loop'
/day/{      # if the pattern space matches 'day'
  s///g     # remove all occurrence of 'day' from the pattern space
  b loop    # go back to the label 'loop'
}

如果未执行命令的b loop部分,则打印模式空间的当前内容并读取下一行。

答案 4 :(得分:2)

使用bash:

str=ddayaynightday
while true; do tmp=${str//day/}; [[ $tmp = $str ]] && break; str=$tmp; done
echo $str

答案 5 :(得分:0)

好的,这里是bash中的whilestrlen。 使用它们可以实现我的想法:

  

重复直到它的长度停止变化。

既没有办法设置标志也没有办法写这样的正则表达式,以“替换直到不再匹配”。