Home > database >  With sed, delete only a certain matched address range
With sed, delete only a certain matched address range

Time:06-17

The following text has 2 address ranges that will be matched using sed -n '/#/,/\$/p':

foo
#bar
foo
$
foobar
#foo
$bar
foobar

How can I delete a specific match only (1st, 2nd...)? Below should be the output for deleting 2nd match only:

foo
#bar
foo
$
foobar
foobar

CodePudding user response:

If you know the line numbers, then you can target the Nth match.

Assume your input file has the following content

$ cat input_file
Match 1
#bar
foo
$
Match2
#foo
$bar
Match 3
#bar
foo
$
Match 4
#foo
$bar
Match 5
#bar
foo
$
Match 6
#foo
$bar

To remove the first match, anything from line 1 to the end of the first range will suffice.

$ sed '/#/,/\$/{1,/\$/d}' input_file
Match 1
Match2
#foo
$bar
Match 3
#bar
foo
$
Match 4
#foo
$bar
Match 5
#bar
foo
$
Match 6
#foo
$bar

To remove the fourth match, the range can start from the 12th or 13th line

sed '/#/,/\$/{13,/\$/d}' input_file
Match 1
#bar
foo
$
Match2
#foo
$bar
Match 3
#bar
foo
$
Match 4
Match 5
#bar
foo
$
Match 6
#foo
$bar

CodePudding user response:

This might work for you (GNU sed):

sed -E '/#/{x;s/^/x/;x};/#/,/\$/{x;/^x{2}$/{x;d};x}' file

Set up a counter in the hold space and use it to determine which range to delete.

This has the added advantage of being able to delete a range of ranges e.g.

sed -E '/#/{x;s/^/x/;x};/#/,/\$/{x;/^x{2,3}$/{x;d};x}' file

This will delete the second and third ranges.

  • Related