0

For first question, example,

A  
B  
C  
B  
D  

Need to insert E after FIRST MATCH of B.

A  
B  
E  
C  
B  
D  

For second question example,

A  
B  
C  
B  
D  
E  
F  

Need to remove only D and E, 2 lines after second pattern match.

A  
B  
C  
B  
F 
Allan
  • 12,117
  • 3
  • 27
  • 51
Colin
  • 53
  • 1
  • 6
  • 2
    Possible duplicate of [Insert line after first match using sed](https://stackoverflow.com/questions/15559359/insert-line-after-first-match-using-sed) Even though it really has two questions making it a bit broader... Perhaps it could still be salvaged with a little refocusing? Also showing some effort towards a solution never hurts. – Ondrej K. Jun 14 '18 at 22:22

2 Answers2

2

This might work for you (GNU sed):

sed -e '/B/!b;x;s/^/x/;/^x\{1\}$/{x;aE' -e 'b};x' file

sed -e '/B/!b;x;s/^/x/;/^x\{2\}$/{x;n;N;d};x' file

Both these solutions can be split into three parts:

  • Focus on a particuar regexp
  • Counting
  • Conditional on the above

If the regexp is not true, continue as normal

If the regexp is true, count it by appending a character (x) to the hold space for each occurrence.

Condtional on the count (in the first solution, 1 and the second solution, 2) carry out an action.

In the first solution:

  • append a line containing E

In the second solution:

  • print the current line
  • append the next two lines
  • delete the current pattern space

If the conditional is not true, continue as normal.

N.B. the first solution can be shortened using ranges:

sed '0,/B/!b;//aE' file

or for variations of sed that do not allow GNU extentions (0,address)

sed -e '/B/{aE' -e ':a;n;ba}' file
potong
  • 55,640
  • 6
  • 51
  • 83
1

Implementation done with

sed --version
sed (GNU sed) 4.2.2

Q1:

$ more input
A
B
C
B
D
B
D

sed:

$ sed -n -e '/^B$/!{p};/^B$/{p;x;/^$/{a E' -e '}}' input
A
B
E
C
B
D
B
D

Q2:

$ more input2
A
B
C
B
D
E
F

sed:

$ sed -n '/^B$/{p;H};/^B$/!{x;/B\nB1\?$/{s/.*/&1/;x;b;};x;p}' input2
A
B
C
B
F
Allan
  • 12,117
  • 3
  • 27
  • 51