使用sed删除两个模式之间的行(不包括这两个模式)。

16

好的。

我知道这是一个微不足道的问题,但是:如何删除文件中两个已知模式/单词之间的行:

pattern1
garbage
pattern2

以获得:

pattern1
pattern2

还有谁知道学习sed的好(简单易懂的!)资源?带有许多清晰的例子?


6个回答

20
sed -n '/pattern1/{p; :a; N; /pattern2/!ba; s/.*\n//}; p' inputfile

解释:

/pattern1/{         # if pattern1 is found
    p               # print it
    :a              # loop
        N           # and accumulate lines
    /pattern2/!ba   # until pattern2 is found
    s/.*\n//        # delete the part before pattern2
}
p                   # print the line (it's either pattern2 or it's outside the block)

编辑:

一些版本的sed需要逐步输入指令才能正确执行:

sed -n -e '/pattern1/{' -e 'p' -e ':a' -e 'N' -e '/pattern2/!ba' -e 's/.*\n//' -e '}' -e 'p' inputfile

它给了我 sed: -e expression #1, char 58: Unknown option to 's'。我的 sed 版本是 3.02。 - kasper
@ Dennis:哦,从编辑处得到的版本正在执行正确的操作。再次感谢! - kasper
4
使用更简单的命令来实现同样的功能:sed -n '/pattern1/,/pattern2/p; /pattern2/q' inputfile - user332325
@pooh:你的第一个代码在这个测试数据中无法正常工作(带有“xxx”的行不应该被打印,其他所有内容都应该被打印):echo -e 'aaa\npattern1\ncccxxx\ndddxxx \npattern2\nfff\nggg\npattern1\nAAAxxx\nBBBxxx \nCCCxxx\nDDDxxx\npattern2\nEEE\nFFF' - Dennis Williamson
@DennisWilliamson:我尝试了你的测试数据和pooh的建议,它在我的OSX上运行良好(也许这就是原因?)。为什么会失败,或者为什么应该失败呢? - jakesandlund
显示剩余3条评论

17

这将适用于GNU和BSD sed:

sed '/pattern1/,/pattern2/{//!d;}' file

6
如果其他人在使用BSD sed(即Mac OSX)时遇到错误“d命令末尾有额外字符”,只需在d后面添加;,就像这样: sed '/pattern1/,/pattern2/{//!d;}' file。请注意,此操作不会更改原始意思,只是纠正错误并使其在Mac OSX上运行。 - rkd
2
你如何包括这些模式? - qodeninja

5
这可以轻松地使用awk完成:
BEGIN { doPrint = 1; }
/pattern1/ { doPrint = 0; print $0; }
/pattern2/ { doPrint = 1; }
{ if (doPrint) print $0; }

我发现sed信息和awk相比较容易阅读,有很多例子。请参考sed infoawk

4
awk '/pattern1/{g=1;next}/pattern2/{g=0;next}g' file

2
这个sed代码同样有效:
sed '/PATTERN1/,/PATTERN2/d' FILE

虽然不是 OP 想要的,但这个答案作为 @potong 的回答的“包容性”版本效果很好。 - Sadi

0

你也可以使用Unix文本编辑器ed:

echo '
pattern1
garbage
pattern2
' > test.txt

cat <<-'EOF' | sed -e 's/^ *//' -e 's/ *$//' | ed -s test.txt &>/dev/null
  H
  /pattern1/+1,/pattern2/-1d
  wq
EOF

更多信息请参见:使用ed文本编辑器从脚本中编辑文件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接