Sed 删除 2 个模式之间的所有内容,但不包括模式

Sed delete everything between 2 patterns, but not including the patterns

我已经找到了几个例子,但是 none 完全符合我的要求。

我想删除 1 和其他几种可能模式之间的所有内容,但不包括模式本身。模式对仅每行,不跨多行。

例如

:1543453 Brown Fox
:789 123456 Cat
:abcdef Yellow Duck

:Brown Fox
:Cat
:Yellow Duck

所以要匹配的第一个模式是“:”,第二个是 "Brown" OR "Cat" OR "Yellow"

蛮力和无知,有时效果很好:

sed -e 's/^:.* Brown/:Brown/' \
    -e 's/^:.* Cat/:Cat/' \
    -e 's/^:.* Yellow/:Yellow/' \
    data-file.txt

您可以将 'extended regular expressions' 与 -E(BSD、Mac、Linux)或 -r(Linux仅)选项:

sed -E 's/^:.* (Brown|Cat|Yellow)/:/' data-file.txt

两者都在示例数据上产生了所需的输出。

请注意,使用的 .* 是 'greedy'。给定输入文件:

:1543453 Brown Fox
:789 123456 Cat
:abcdef Yellow Duck
:quantum mechanics eat Yellow Ducks for being yellow (but leave Yellow Dafodils alone)

两个脚本都产生:

:Brown Fox
:Cat
:Yellow Duck
:Yellow Dafodils alone)

您需要 Perl 或 sed 增强的 PCRE(Perl 兼容正则表达式)或其他一些程序,以避免贪婪。例如:

$ perl -n -e 'print if s/^:.*? (Brown|Cat|Yellow)/:/' data-file.txt
:Brown Fox
:Cat
:Yellow Duck
:Yellow Ducks for being yellow (but leave Yellow Dafodils alone)
$