[英]Choose block print section of file between two regular expressions using sed or awk
sed -n '/pattern1/,/pattern2/p'
pattern1
a
b
pattern2
cd
pattern1
ef
pattern2
gh
pattern1
ef
pattern2
這將在所有匹配的pattern1和pattern2之間生成輸出
但是我如何選擇要打印的塊,就像僅打印最后一個匹配的圖案塊或僅第一個匹配的圖案塊?
這是使用awk的一種方法:
$ awk '/pattern1/{++f;p=1}p&&f==2;/pattern2/{p=0}' file
pattern1
ef
pattern2
中間的數字2
控制哪個事件被打印(在本例中為第二個)。
當打開樣式匹配時, f
遞增,並設置p
標志。 當關閉模式匹配時, p
標志未設置。 僅當設置了p
標志並且f
具有特定值時才打印行。
如果需要,可以從外殼中傳遞值:
$ c=2
$ awk -v c="$c" '/pattern1/{++f;p=1}p&&f==c;/pattern2/{p=0}' file
pattern1
ef
pattern2
要始終打印該范圍內的最后一個匹配項,可以使用一個數組:
$ awk '{a[NR]=$0}/pattern1/{s=NR}/pattern2/{e=NR}END{for(i=s;i<=e;++i)print a[i]}' file
pattern1
ef
pattern2
文件中的每一行都按順序存儲在數組a
。 每次匹配開始或結束模式時, s
和e
將被當前行號NR覆蓋。 最后,打印您感興趣的元素。
這種方法的潛在缺點是整個文件的內容都存儲在內存中,但是除非您有非常大的文件,否則這可能不是問題。
另一種awk方式
awk -vM=2 '(x+=/pattern1/)==M&&x+=/pattern2/' file
pattern1
ef
pattern2
-vM=2
將M設置為您要查找的任何事件
(x+=/pattern1/)==M
每次出現pattern1
x
遞增,並檢查其是否等於M
&&x+=/pattern2/
如果確實這樣做,則每次出現pattern2
時都會增加它,因此當它到達pattern 2時,它將打印該行,但不會更多,因為現在它將大於M。
awk的默認操作是打印。
這僅存儲在內存中看到的最后一個塊。
awk 'x+=/pattern1|pattern2/{!y++&&B="";B=B?B"\n"$0:$0;x==2&&y=x=0}END{print B}' file
pattern1
ef
pattern2
每次出現模式1或2時增加x
未設置y時沖洗B(找到新設置),然后設置y
如果x存在,則將行添加到變量B
如果計數為2,則表示未設置x和y,表示都已看到。
Perl進行救援!
perl -ne 'push @keep, $_ if (/pattern1/ and @keep = ("")) .. /pattern2/;
}{ print @keep'
說明:匹配被存儲在@keep,時被排空pattern1
匹配。 因此,@ keep將包含在處理完整個輸入之后的最后一個匹配項。
perl -ne 'push @keep, $_
if (/pattern1/ and ++$c and @keep = "")
.. ($e = /pattern2/);
print(@keep), last if $e and 2 == $c'
# ^
# |
# the second match
$ c計算比賽次數。 $ e表示比賽結束。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.