[英]awk compare 2 files, print match and nonmatch lines;3rd column of first file and 2nd column of second file
[英]awk to print 3 lines above match until second match
我的行很長,我想選擇性地在上面打印START + 3行,直到包括END。 問題是START和END之間的長度是可變的,但是我始終希望start上方的三行。
我嘗試了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
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/
之間的所有記錄
#!awk -f
{
foo[NR] = $0
}
/START/ {
bar = NR - 3
}
/END/ {
while (bar++ <= NR)
print foo[bar]
}
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
>
相同主題的相似但更容易理解的變化:
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$/
或者代替模式匹配,在所有情況下都應使用直接字符串比較,如$0=="START"
。
輸入文件:
GEF
START
EDG
EFG
GAD
END
CDA
EFA
DAD
ABC
DEF
GEF
START
EDG
EFG
GAD
END
CDA
輸出:
GEF
START
EDG
EFG
GAD
END
GEF
DEF
ABC
START
EDG
EFG
GAD
END
一種對您的需求的可能解釋的可能解決方案:
$ 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
如果有1個或多個START / END塊並且您不希望第一個START到最后一個END,則可以使用。
如果START和END僅出現一次,則可以將grep
與如下上下文一起使用:
grep -B 3 -A 99999 START file | grep -B 99999 END
即START before
3行,之后最多99999行,然后END之前最多99999行。
使用TAC
如果文件中有多個END / STARTS,則應該可以使用
tac file | awk '/END/{x=4}y&&x{x--}/START/{y=x}x' | tac
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.