echo ddayaynightday | sed 's/day//g'
运行结果为 daynight
有没有办法使其替换到没有匹配为止?
我个人偏爱的形式,针对这种情况:
echo ddayaynightday | sed -e ':loop' -e 's/day//g' -e 't loop'
这个与其他人的相同,只是使用了多个-e命令来制作三行,并使用t
结构——这意味着“如果您进行了成功的替换,则分支”——进行迭代。
t
条件跳转对我来说更清晰,而不是无条件跳转的模式匹配。 - Christian Semrauecho ddayaynightday | sed ':a;s/day//g;ta'
night
g
标志故意不会重新匹配替换部分的字符串。你需要做的有点不同。尝试这个:
echo ddayaynightday | sed $':begin\n/day/{ s///; bbegin\n}'
sed ':begin;/day/{ s///; bbegin }'
$'... string with escapes...'
结构更美观。对于非常长的脚本,使用-f file
可能更好。在这种特定情况下,多个-e
命令也可以工作。 - torek$ 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
部分未被执行,则会打印模式空间的当前内容,并读取下一行。sed: 1: ":loop;/day/{s/day//g;b ...": unused label 'loop;/day/{s/day//g;b loop}'
。 - Grahams///g
和b loop
之间),但在其他位置不行,同时在花括号周围需要换行。我认为这是GNU sed相比其他变体的巨大优势之一。这极大地扩展了sed一行命令的能力。 :) - ghoti使用bash:
str=ddayaynightday
while true; do tmp=${str//day/}; [[ $tmp = $str ]] && break; str=$tmp; done
echo $str