sed:在同一行内,一旦达到某个字符串就停止重复模式替换

use*_*016 4 sed

我在任何地方都找不到答案。这听起来很简单,但我开始认为可能并非如此。

我希望 sed 在此字符串中的 STOP 之前删除所有 CAT:

two CAT two four CAT CAT seven one STOP four CAT two CAT three
Run Code Online (Sandbox Code Playgroud)

所以我希望的输出是:

two two four seven one STOP four CAT CAT two CAT three
Run Code Online (Sandbox Code Playgroud)

字符串中的任何位置都可以有任意数量的 CAT。停止标记也可以在任何地方,但只是其中之一,并且总是拼写为 STOP。

(编辑:正如下面所指出的,我的问题是模棱两可的 - CAT 必须有相邻的空格还是可以有任何字符与其边界?也许只有非字母数字字符才可以?展示我的实际用例很激烈(一个大的 bash 函数)所以我简化了,太多了。读者请记住,下面的解决方案可能会对邻接做出不同的假设。谢谢)

ste*_*ver 10

您可以在循环中一次替换一个,直到在CAT之前没有更多的s STOP

$ echo 'two CAT two four CAT CAT seven one STOP four CAT two CAT three' |
    sed -e :a -e '/CAT.*STOP/s/CAT //;ta'
two two four seven one STOP four CAT two CAT three
Run Code Online (Sandbox Code Playgroud)

  • 我真的很想知道为什么这被否决了。 (3认同)
  • 我认为使用 `sed` 没有问题。while 循环就是一个 while 循环,无论它是否实际包含关键字“while”。 (2认同)

Qua*_*odo 5

使用任何 awk:

awk '{while($0~/CAT .*STOP/)sub(/CAT /,"")}1' file
Run Code Online (Sandbox Code Playgroud)
$ echo 'two CAT two four CAT CAT seven one STOP four CAT two CAT three' |
  awk '{while($0~/CAT .*STOP/)sub(/CAT /,"")}1'
two two four seven one STOP four CAT two CAT three
Run Code Online (Sandbox Code Playgroud)


Sun*_*eep 5

perl

perl -pe 's/CAT (?=.*STOP)//g'
Run Code Online (Sandbox Code Playgroud)

这将CAT STOP在该行后面存在时才替换