3

I'm familiar with using sed to grab lines between two patterns. For example:

$ cat file
A
PATTERN1
B
PATTERN2
C
$ sed -n '/PATTERN1/,/PATTERN2/p' file
PATTERN1
B
PATTERN2

What I'd like to do, however, is generate this output:

PATTERN1
B
PATTERN2
C

I've come across the {n;p} syntax (example), but I can't seem to shoehorn this into the type of pattern matching I'm doing in this example problem.

chad512
  • 77
  • 6
  • 2
    `sed -En '/PATTERN1|PATTERN2/{N;p}' file`? – Cyrus Jun 03 '20 at 15:14
  • @Cyrus interesting trick.. will fail only if there's no line between the two markers – Sundeep Jun 03 '20 at 15:22
  • 1
    ... and it fails if there is more than one line between `PATTERN1` and `PATTERN2`. It only works in that one particular case chad512 described. – Cyrus Jun 03 '20 at 15:46

2 Answers2

3

You can use N (syntax here is based on GNU sed)

$ sed -n '/PATTERN1/,/PATTERN2/{/PATTERN2/N; p}' ip.txt 
PATTERN1
B
PATTERN2
C


Using awk

$ awk '/PATTERN1/{f=1} f || (c && c--); /PATTERN2/{f=0; c=1}' ip.txt
PATTERN1
B
PATTERN2
C

which you can generalize using:

awk -v n=2 '/PATTERN1/{f=1} f || (c && c--); /PATTERN2/{f=0; c=n}'


Further Reading:

Sundeep
  • 23,246
  • 2
  • 28
  • 103
1

This might work for you (GNU sed):

sed -n '/PATTERN1/,/PATTERN2/{p;/PATTERN2/{n;p}}' file

Alternative:

sed '/PATTERN1/{:a;n;/PATTERN2/!ba;n;p};d' file
potong
  • 55,640
  • 6
  • 51
  • 83