AWK – Print Ranges from Last Occurrence of Pattern to First Occurrence of Another

awksedtext processing

Good morning, this is extremely similar to the question Grep From the Last Occurrence of a Pattern to Another Pattern (several months old), while adding a little more detail.

I am trying to write a UNIX script for a file with multiple duplicate patterns, followed by the pattern I am looking for. However I do not have 'tac' or 'tail -r' (using the UNIX emulator, MKS Toolkit), and am looking to return the last occurrence of Pattern1 before Pattern2, followed by the data in between Pattern1 and Pattern2, and then Pattern2 also. The Patterns in this case would be 'Condition 1' and 'Condition 2':

output.out:

...
Condition 1: A
data1
Condition 1: B
data2
Condition 2: C
data3
Condition 1: D
data4
Condition 1: E
data5
Condition 2: F
...

I'd like to write an awk (or sed, but figured awk would be the right tool) script to return:

Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F

I figure it's some form of the line below, but I can't get the syntax right:

awk '/Condition 1/ {acc = $0;} /,/Condition 2/ {print ?}' output.out

Working the '/,/' is where I seem to be having hangups. Was wondering if anyone had any advice, would be much appreciated. Many thanks for any help and time related to this question.

Best Answer

Try:

$ awk 'f{a=a"\n"$0} /Condition 1/{a=$0; f=1} f && /Condition 2/{print a; f=0}' output.out 
Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F

How it works

  • f{a=a"\n"$0}

    If the variable f is true (nonzero), then append the current line onto the end of variable a.

  • /Condition 1/{a=$0; f=1}

    If the current line contains Condition 1, then set s to the current line and set variable f to 1.

  • f && /Condition 2/{print a; f=0}

    If f is true and the current line contains Condition 2, then print variable a and set f back to zero.

Related Question