我有很长的行列表,我想有选择地打印START + 3行,直到END包括。问题是START和END之间的长度是可变的,但我总是希望上面的三行开始 我试过awk:
awk '/START/,/END/' file.txt
但是我无法找到如何在START之上加入三行的方法。 真的很感激任何提示 谢谢!
输入
EFA
DAD
ABC
DEF
GEF
START
EDG
EFG
GAD
END
CDA
结果
ABC
DEF
GEF
START
EDG
EFG
GAD
END
答案 0 :(得分:1)
awk '/START/ { if (a) print a; if (b) print b; if (c) print c; }\
{ a=b; b=c; c=$0; }\
/START/,/END/' file.txt
<强>解释强>
当遇到匹配/START/{if(a)print a;if(b)print b;if(c)print c}
的行时, /START/
打印缓冲区记录,跳过任何空的。
{a=b;b=c;c=$0}
移位缓冲区记录,如果需要更多记录,则可以使用数组。
/START/,/END/
打印/START/
和/END/
答案 1 :(得分:1)
#!awk -f
{
foo[NR] = $0
}
/START/ {
bar = NR - 3
}
/END/ {
while (bar++ <= NR)
print foo[bar]
}
答案 2 :(得分:1)
awk '/START/{print x3"\n"x2"\n"x;p=1}
/END/{print;p=0}
{x3=x2}
{x2=x}
{x=$0}p' your_file
测试:
> cat temp
EFA
DAD
ABC
DEF
GEF
START
EDG
EFG
GAD
END
CDA
> awk '/START/{print x3"\n"x2"\n"x;p=1}/END/{print;p=0}{x3=x2}{x2=x}{x=$0}p' temp
ABC
DEF
GEF
START
EDG
EFG
GAD
END
>
答案 3 :(得分:1)
同一主题的类似但可能更容易理解的变体:
awk '/START/{for(i=1;i<4;++i)if(NR-i in a)print a[NR-i]}{a[NR]=$0;delete a[NR-3]}/START/,/END/' inputfile
在中间它只存储最后三行,如果有第四行则会丢弃。如果找到字符串START
,则会打印前三行(仅当它们存在时)以及START
和END
之间的任何行。
如果START
和END
应该是准确的,那么模式应该是/^START$/
和/^END$/
或者代替模式匹配,应该像{{{{{{ 1}}在所有情况下。
输入文件:
$0=="START"
输出:
GEF
START
EDG
EFG
GAD
END
CDA
EFA
DAD
ABC
DEF
GEF
START
EDG
EFG
GAD
END
CDA
答案 4 :(得分:1)
可能解释您的要求的一种可能的解决方案:
$ awk '{a[NR]=$0} /START/{s=NR} /END/{for (i=(s-3);i<=NR;i++) print a[i]}' file
ABC
DEF
GEF
START
EDG
EFG
GAD
END
如果有一个或多个START / END块并且你不想让第一个START结束END,那么它将起作用。
答案 5 :(得分:0)
如果START和END只出现一次,您可以使用grep
这样的上下文:
grep -B 3 -A 99999 START file | grep -B 99999 END
即。 3行before
START和最多99999行,然后在END之前最多99999行。
答案 6 :(得分:0)
使用tac
如果文件中有多个END / STARTS
,则应该有效tac file | awk '/END/{x=4}y&&x{x--}/START/{y=x}x' | tac