Question and answer based on my own question and answer in How to select lines between two patterns?
I have a file like the following and I would like to print the lines that appear between the patterns PAT1
and PAT2
.
1
2
PAT1
3 - primer bloque
4
PAT2
5
6
PAT1
7 - segundo bloque
PAT2
8
9
PAT1
10 - tercer bloque
I've read How to select lines between two marker patterns which may occur multiple times with awk/sed but I'm curious to see all the possible combinations, both printing the patterns and not.
How can I select the lines between two patterns?
Print lines between PAT1 and PAT2
Or, using variables:
How does it work?
/PAT1/
the lines that contain the pattern/PAT1/
; similarly, the same goes for/PAT2/
and lines containing the pattern/PAT2/
./PAT1/{flag=1}
initializes the semaphoreflag
when the patternPAT1
appears on a line./PAT2/{flag=0}
turn off the traffic lightflag
when the patternPAT2
is in a line.flag
it is a semaphore and acts as a pattern. When it has a value1
, it is interpreted as True and triggers the default action ofawk
, which is to execute{print $0}
, that is, to print the current line. In this way, all the lines that appear from when itPAT1
appears until it does are printedPAT2
. This also prints all lines from thePAT1
last occurrence to the end of the file, if there is noPAT2
before.Print lines between PAT1 and PAT2 - not including PAT1 and PAT2
This is used
next
to skip the line containing the patternPAT1
so that it is not printed.This use of
next
can be removed by reordering the blocks:awk '/PAT2/{flag=0} flag; /PAT1/{flag=1}' fichero
.Print lines between PAT1 and PAT2 - including PAT1
When put
flag
at the end of everything, it executes the action that was defined in PAT1 or PAT2. That is, to print in PAT1 and not to print in PAT2.Print lines between PAT1 and PAT2 - including PAT2
When put
flag
at the beginning of the whole, it executes the action that was previously defined. Therefore, it prints the closing pattern but not the starting pattern.Print lines between PAT1 and PAT2 - excluding the lines between the last PAT1 and the end of the file if no other PAT2 appears
This is based on Ed Morton's solution .
In a single line:
This saves the selected lines in a buffer: from the moment a line matches the PAT1 pattern, it adds all the lines until PAT2 is found. At that time, it prints the saved lines and flushes the buffer.