【发布时间】:2018-05-12 21:15:00
【问题描述】:
我在这方面找到了一些示例,但没有一个完全符合我的要求。
我想删除 1 和其他几种可能的模式之间的所有内容,但不包括模式本身。模式对仅是每行,而不是多行。
例如
:1543453 Brown Fox
:789 123456 Cat
:abcdef Yellow Duck
到
:Brown Fox
:Cat
:Yellow Duck
所以第一个匹配的模式是“:”,第二个是“棕色”或“猫”或“黄色”
【问题讨论】:
我在这方面找到了一些示例,但没有一个完全符合我的要求。
我想删除 1 和其他几种可能的模式之间的所有内容,但不包括模式本身。模式对仅是每行,而不是多行。
例如
:1543453 Brown Fox
:789 123456 Cat
:abcdef Yellow Duck
到
:Brown Fox
:Cat
:Yellow Duck
所以第一个匹配的模式是“:”,第二个是“棕色”或“猫”或“黄色”
【问题讨论】:
有蛮力和无知,有时效果很好:
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 或使用 PCRE(Perl 兼容的正则表达式)或其他一些程序增强的 sed,以避免贪婪。例如:
$ 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)
$
【讨论】:
pat1=":";pat2="(Cat|Yellow|Brown)";sed -r "s/(${pat1}).*(${pat2})/\1\2/" inputfile
: 不一定是最好的技术;使用捕获并在替换中引用它更通用。
sed -E 's/(Brown|Cat|Yellow)/\x01\1/; s/^:.*\x01/:/' data-file.txt来避免贪婪(当pattern2在pattern1之后)。
sed 在运行 macOS 10.13.4 的 Mac 上测试了我展示的片段。