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

时间:2018-05-12 21:15:00

标签: bash sed bsd

我已经找到了一些这方面的例子,但没有一个能够完全符合我的要求。

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

例如

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

:Brown Fox
:Cat
:Yellow Duck

所以匹配的第一个模式是":"第二个是"布朗"或者" Cat"或"黄色"

1 个答案:

答案 0 :(得分:2)

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

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

您可以在-E(BSD,Mac,Linux)或-r(仅限Linux)选项中使用“扩展正则表达式”:

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

两者都在样本数据上产生所需的输出。

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

: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)/:\1/' data-file.txt
:Brown Fox
:Cat
:Yellow Duck
:Yellow Ducks for being yellow (but leave Yellow Dafodils alone)
$