[英]Print all lines between two patterns (which may not be pairs) with AWK/SED/GREP
我知道這個問題有多個實例,例如打印兩個模式之間的所有行,排他性,僅第一個實例(在 sed、AWK 或 Perl 中)但我的問題是如果這兩個模式可能不配對 - 例如
給定輸入
PATTERN1
bbb
ccc
ddd
eee
fff
PATTERN1
ggg
hhh
iii
PATTERN2
jjj
PATTERN2
kkk
我希望最短范圍作為輸出:
ggg
hhh
iii
這可能嗎?
您能否僅在 GNU awk
嘗試根據您顯示的示例進行跟蹤、編寫和測試。
awk '
/PATTERN1/ && found1 && !found2{
found1=found2=val=""
}
/PATTERN1/{
found1=1
next
}
/PATTERN2/{
found2=1
if(found1){
print val
}
found1=found2=val=""
next
}
{
val=(val?val ORS:"")$0
}
' Input_file
給定樣本的輸出將是:
ggg
hhh
iii
說明:為以上添加詳細說明。
awk ' ##Starting awk program from here.
/PATTERN1/ && found1 && !found2{ ##Checking if PATTERN1 in current line and found1 is SET and found2 is NOT SET then do following.
found1=found2=val="" ##Nullifying found1, found2 and val variables here.
}
/PATTERN1/{ ##Checking condition if PATTERN1 is found then do following.
found1=1 ##Setting found1 here for flagging.
next ##next will skip all further statements from here.
}
/PATTERN2/{ ##Checking condition if PATTERN2 is found then do following.
found2=1 ##Setting found2 here for flagging.
if(found1){ ##Checking condition if found1 is SET then do following.
print val ##Printing val here.
}
found1=found2=val="" ##Nullifying found1, found2 and val here.
next ##next will skip all further statements from here.
}
{
val=(val?val ORS:"")$0 ##Creating val which has current line value and keep appending it with new line.
}
' Input_file ##Mentioning Input_file name here.
在awk
,你可以通過保存做PATTERN..
每一次比較一個PATTERN..
遇到。 在兩者之間,您將元素保存在一個數組中,當您有兩個不匹配的模式時——您輸出數組的內容。 否則你清空數組並重置你的計數器,例如
awk '! /PATTERN/ {
a[++n]=$0
}
/PATTERN/ {
if ($0 != lastptrn)
for (i=1; i<=n; i++)
print a[i]
delete a
n=0
lastptrn=$0
}
' file
輸出
ggg
hhh
iii
如果Perl
恰好是您的選擇,請您嘗試:
perl -0777 -ne '/.*PATTERN1\n(.*?)PATTERN2/s && print $1' input
結果:
ggg
hhh
iii
-0777
選項告訴Perl
一次-0777
所有行。s
選項告訴Perl
在元字符中包含換行符.
..*PATTERN1\\n
位置直到最后一個PATTERN1
結束。(.*?)
指定最短匹配並為匹配的行分配$1
。其他:
$ awk '
/PATTERN1/ { # at starting pattern
f=1 # flag up
b="" # reset buffer
next # to exclude the start pattern
}
/PATTERN2/ { # at ending pattern
print b # output buffer
exit # no need to continue to the end
}
f { # when flag up
b=b (b==""?"":ORS) $0 # buffer records
}' file
要包括開始和結束標記,請刪除next
並在/PATTERN2/ {...}
之前移動f {...}
/PATTERN2/ {...}
這可能對你有用(GNU sed):
sed -n '/PATTERN2/{g;/PATTERN1/{s/[^\n]*\n//p;q}};H;/PATTERN1/h' file
概述:將行從PATTERN1
到但不包括PATTERN2
復制到保留空間中,然后打印保留空間減去第一行。
處理:將所有行附加到保持空間,當匹配時用PATTERN1
的內容替換保持空間。
當PATTERN2
匹配時,用保留空間覆蓋模式空間,如果模式空間包含PATTERN1
,則刪除第一行,打印模式空間的內容並退出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.