Answers:
如果您具有GNU sed(因此是非嵌入式Linux或Cygwin):
sed '/bar/,+1 d'
如果您有bar
连续两行,这将删除第二行而不进行分析。例如,如果您有一个三行文件bar
/ bar
/ foo
,则该foo
行将保留。
bar
s,所以这个很容易记住。
sed '/bar/d'
如果您只想“删除包含某些字符串的行”而不是下一个。
sed '/math/q'
sed '/bar/d'
如果bar
可能连续出现,您可以执行以下操作:
awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile
可以通过更改上面的2行和要删除的行数(包括匹配的行)来更改删除多于2行的内容。
如果没有,可以sed
使用@MichaelRollins的解决方案轻松完成,或者:
sed '/bar/,/^/d' < infile > outfile
/bar/
为/bar|baz|whatever/
。在sed
那种语法似乎不起作用。
sed
使用“扩展”正则表达式。此处有更多信息:gnu.org/software/sed/manual/html_node/…。请注意,这也适用grep
。这是我自己的工作示例:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
。
我不精通sed,但是用awk很容易做到:
awk '/bar/{getline;next} 1' foo.txt
awk脚本的内容为:对于包含bar的行,获取下一行(getline),然后跳过所有后续处理(下一步)。末尾的1个图案将打印剩余的行。
如评论中所指出,上述解决方案不适用于Continuous bar
。这是一个经过修订的解决方案,其中考虑到了这一点:
awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt
现在,我们继续阅读以跳过所有/ bar /行。
grep -A
100%,您还需要bar
正确处理任意数量的连续行(通过删除整个块和之后的1行)。
您将需要利用sed的脚本功能来完成此任务。
$ sed -e '/bar/ {
$!N
d
}' sample1.txt
样本数据:
$ cat sample1.txt
foo
bar
biz
baz
buz
“ N”命令将输入的下一行追加到模式空间中。这与模式匹配中的行(/ bar /)相结合,将成为您要删除的行。然后,您可以使用“ d”命令正常删除。
sed -e '/bar/{N;d}' sample1.txt
如果在比赛之后立即删除任何行,则您的sed
程序将不得不考虑连续比赛。换句话说,如果您删除匹配后也匹配的行,则可能也应该删除该行。
它的实现方式非常简单-但是您必须稍稍落后一些。
printf %s\\n 0 match 2 match match \
5 6 match match match \
10 11 12 match 14 15 |
sed -ne'x;/match/!{g;//!p;}'
0
6
11
12
15
它通过交换读入的每一行的保持空间和模式空间来工作,因此每次都可以将最后一行与当前行进行比较。因此,当sed
读取一行时,它将交换其缓冲区的内容-而前一行则是其编辑缓冲区的内容,而当前行则置于保留空间中。
因此,请sed
检查上一行是否与匹配match
,如果!
找不到,则运行该{
函数}
中的两个表达式。sed
将g
等通过覆盖模式空间保留空间-这意味着当前行是随后用双手保持和模式空间-然后它会//
检查是否有一个匹配它最近正则表达式编译- match
-如果它没有match
它被p
冲洗。
这意味着如果没有一个线仅印刷和紧邻的前一行不。它还放弃了对es 序列的任何不必要的交换。match
match
match
如果您想要一个可以删除之后任意数量行的版本,match
则需要做更多的工作:
printf %s\\n 1 2 3 4 match \
match match 8 \
9 10 11 12 13 \
14 match match \
17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep
...将5替换为您要删除的行数(包括匹配的行) ...
1
2
3
4
12
13
14
21