0

I have a file from which I need the pattern occurring just before another pattern as such:

PAT1  
coord  
data  
data  
PAT1  
coord  
data  
data  
data  
PAT1  
coord  
data  
PAT2  
PAT1  
coord  
...

The file will always have the flow PAT1 --> coord --> data, but there will not always be a PAT2 after data. Wanted output: coord -- The one between a PAT2 and the PAT1 immediately before it.

That is, expected output should be:

coord

Since there is only one PAT2 in the example given.

I've been looking through lots of questions and answers on this and other sites, but can't find anything quite right. For example:

This would be great if there was a PAT2 for every PAT1-
https://stackoverflow.com/questions/38972736/how-to-print-lines-between-two-patterns-inclusive-or-exclusive-in-sed-awk-or/38972737#38972737

This answer would be convenient if coord were a set number of lines up from PAT2-
awk print a match only if last record before other match

And so on.

Any suggestions are greatly appreciated. I am open to any methods (sed, awk, grep, etc.).

1
  • @thanasisp Done. It will always go PAT1 coord data, but then from there it will either go PAT1... or PAT2 PAT1 .... I want the coord between PAT2 and the PAT1 immediately before it. Additionally, coord is constant -- it will follow the same pattern in any file of this type. Nov 3, 2020 at 19:27

1 Answer 1

0

A more representative sample input would be the same with line numbering, in order to identify which line we are printing to the output.

> nl file
     1  PAT1  
     2  coord  
     3  data  
     4  data  
     5  PAT1  
     6  coord  
     7  data  
     8  data  
     9  data  
    10  PAT1  
    11  coord  
    12  data  
    13  PAT2  
    14  PAT1  
    15  coord  

This awk command will print the line containing the coord pattern, only if found between PAT1 and PAT2, without any other occurence of these two patterns into that block.

awk '/PAT1/{f=1; p=""} p && /PAT2/{print p; exit} f && /coord/{p=$0}' <(nl file)
    11  coord  

f is used to indicate that PAT1 has been found, this flag is used to activate matching for any coord following. Also p is emptied for every PAT1 found, this ensures that we print nothing for a case like PAT1 coord PAT1 text PAT2.

Also we exit after printing, if we want to look for more, we can replace that with resetting the flags.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .