删除2个匹配模式之间的n行,保持第一个匹配并删除第二个匹配

时间:2013-12-24 17:37:58

标签: regex bash sed awk

给出文本文件中的数据:

string1 EP00 37.45 83.83 
save
save
save
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
string2

gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish
gibberish

我想使用sedawk来匹配string1和string 2,然后删除string1和前3行之后的所有内容。我想删除string2,但不删除string1。并删除该文件与下一文本之间的一行。所以预期的输出是:

string1 EP00 37.45 83.83 
save
save
save

如果有帮助(16),两种模式之间总有相同数量的行。我想用sedawk执行此操作,但只能找出一个脚本来删除两者之间的整个数据块,并保留两个字符串:

sed '/string1/,/string2/{//!d}' file >> tr.txt

有没有人知道如何指定保留string1及其后面的三行,并删除两个模式之间的其余行,包括string2?我想使用sedawk执行此操作,无论哪个更容易。

谢谢!

5 个答案:

答案 0 :(得分:5)

你可以使用这个awk:

awk '/^string1/{i=0} /^string1/,/^string2/{i++; if (i<5) print; next}1' file
string1 EP00 37.45 83.83 
save
save
save

答案 1 :(得分:2)

如果你想用awk执行此操作,脚本可能看起来像这样(根据你的评论更新;它现在“循环”,所以它会正确地进行匹配,因为你有多少次string1-string2模式。我意识到你已经得到了一个你接受的答案,但是想给你这个替代方案;它比@ anubhava的答案更“专业”,但它可能会让你深入了解如何制作{{1做“你想要的任何事情”,即使你不是专业人士):

awk

BEGIN { state = 0; } { if($1 == "string1") { state = 1; } if (state == 1) { state = 2; print; next; } if (state > 1 && state < 5) { print; state = state + 1; next; } if ($1 == "string2") { state = 6; next; } if (state == 6) { state = 0; next; } if (state == 0) { print; next; } } 变量基本上告诉你“我在逻辑中的位置”。州是:

state

您可以使用

运行它
0: "normal state", print the line, go to the next
1: "found string2", start printing this line and the next three
2 - 4: printing "the lines that followed string1"
5: Waiting for string2, not printing anything
6: found string2, need to delete the next line
   Having found the next line, we reset the state to 0 again…

我做了这个“行人”,所以你可以确切地看到做了什么,以什么顺序。如果您有任何问题,请告诉我。

答案 2 :(得分:0)

这样的事情:

sed -e '1,/^string1/-1d' -e '/string1/+4,$/d' < file > output

第一个命令从第1行删除到以“string1”开头的行之前的行,第二个命令查找以“string1”开头的行,在此之后计算4行,并从那里删除到结尾。 / p>

如果你的grep版本支持它,你也可以这样做:

grep -A3 "^string1" file > output

答案 3 :(得分:0)

使用GNU sed

sed -n '/^string1/,+3p' file

如果没有GNU sed,请尝试:

sed  -n ':a;/string1/{N;N;N;p;ta;}' file

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed -rn '/string1/{h;d};H;/string2/{x;s/(string1([^\n]*\n){4}).*string2.*/\1/p}' file