简体   繁体   中英

Print lines between two patterns through sed/AWK when there is at least one line between them

I am trying to print lines between two patterns through sed command. But I want to include the line containing Pattern1 Pattern2 in the result when there is some line between them. If there is no line between Pattern1 and Pattern2 exclude line with Pattern1 and Pattern2 also from the file.

PAT1
XXX
XXX
PAT2
PAT1
XX
PAT2
PAT1
PAT2
PAT1
XXX
PAT2

The desired output is :

PAT1
XXX
XXX
PAT2
PAT1
XX
PAT2
PAT1
XXX
PAT2
sed -n '/PAT1/{b A};b B; :A {N;/PAT2/b}; :B /PAT1/,/PAT2/p'

When seeing PAT1, go to branch A. There, read the next line and start again if it contains PAT2. Otherwise, print the lines between PAT1 and PAT2.

This might work for you (GNU sed):

sed -n '/^PAT1/{:a;N;/^PAT2/M!ba;/\n.*\n/p}' file

Collect lines between two patterns and only print if there is at least one line between the patterns.

Or:

sed '/^PAT1/h;//!H;/^PAT2/!d;x;/\n.*\n/!d' file

If a line begins with the first pattern replace whatever is in the hold space. Otherwise append the line to the hold space. If the line does not begin with the second pattern, delete it. Otherwise, swap to the hold space and delete it if there are not at least three lines.

$ sed -n '/^PAT1/{N;/PAT2/d};/^PAT1/,/^PAT2/p' file

首先,如果在连续的行中找到PAT1PAT2PAT2其删除,然后使用range打印内容。

  n N Read/append the next line of input into the pattern space. 

awk to the rescue!

$ awk '/PAT1/        {c=1; out=""} 
       /PAT2/ && c>2 {print out $0} 
       c&&c++        {out=out $0 ORS}' file

PAT1
XXX
XXX
PAT2
PAT1
XX
PAT2
PAT1
XXX
PAT2

I think it can be simplified further, but now reads as the requirements. Start with PAT1 and aggregate lines until PAT2 and print if count of lines is more than 2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM