我想删除包含另一个指定模式的模式的所有实例(方便地在新行上):
MID:
示例输入:
header
BEGIN:
1abc
7wurw
END:
BEGIN:
22xyz
MID:
34utov
END:
期望的输出:
header
BEGIN:
1abc
7wurw
END:
我正在寻找可能的一个衬垫。任何帮助将不胜感激。
答案 0 :(得分:4)
使用GNU sed
:
sed -e :a -e '/^BEGIN:/,/^END:/ { /END:/!{$!{N;ba};};/MID:/d;}' inputfile
对于您的输入,它会返回:
header
BEGIN:
1abc
7wurw
END:
答案 1 :(得分:2)
我会使用RS, ORS
变量。这里是单行:
awk -v RS="BEGIN:\n" -v ORS="" '/MID/{next}NR>1{printf RS}7' file
使用您的文件进行测试:
kent$ cat f
header
BEGIN:
1abc
7wurw
END:
BEGIN:
22xyz
MID:
34utov
END:
kent$ awk -v RS="BEGIN:\n" -v ORS="" '/MID/{next}NR>1{printf RS}7' f
header
BEGIN:
1abc
7wurw
END:
请注意,printf RS
不是很好,我用它是因为我知道它是BEGIN:
良好做法printf "%s", RS
答案 2 :(得分:2)
这对我来说对样本有用:
sed '/BEGIN:/,/END:/{/BEGIN/{h;d};H;/END:/!d;x;/MID:/d}' input.txt
我很确定它可以简化很多。
答案 3 :(得分:1)
BEGIN { in_block = 0; }
/BEGIN:/ { in_block = 1; lineno = 0; arr[lineno] = $0; must_write = 1; next; }
/END:/ { in_block = 0;
if (must_write == 1) {
for (i = 0; i <= lineno; ++i) print arr[i]; print;
}
next;
}
/MID:/ { must_write = 0; next; }
in_block == 1 && must_write == 1 { lineno++; arr[lineno] = $0; next; }
in_block == 0 { print }
这应该有效(使用提供的测试用例)。一些awk-wizards可能会找到更密集的解决方案。但是你也可以将这种处理用于其他任务。
答案 4 :(得分:1)
这可能适合你(GNU sed):
sed '/^BEGIN:/{:a;$!{N;/END:/!ba};/MID:/d}' file
答案 5 :(得分:0)
此gnu awk
除以END:
之类的部分,因此不适用于BEGIN:
- END:
,但有效:
awk '!/MID:/{printf "%s%s\n",$0,RT}' RS="END:" t
header
BEGIN:
1abc
7wurw
END:
答案 6 :(得分:0)
sed -n '/BEGIN:/,/END:/ {
H
/END:/ {
s/.*//
x
/\nMID:/ !p
}
}' YourFile
对于OneLiner
sed -n '/BEGIN:/,/END:/{H;/END/{s/.*//;x;/\nMID:/ !p;};}' YourFile
不适用于最后一个; (我必须在我的AIX上保留一个“\ n”)(应该在GNU上运行)
#for AIX
sed -n '/BEGIN:/,/END:/{H;/END/{s/.*//;x;/\nMID:/ !p;}
}' YourFile