sed, delete from MarkA up to but not include MarkB

Expression in math term, I'd like to delete a region of [MarkA,MarkB). I.e., the deletion happens right when the keyword MarkA is encountered, all the way to keyword MarkB, but not including that line (the line including MarkB keyword is left untouched).

Is it possible to do so in sed?

Say my MarkA is ^3, and MarkB is 7,

$ seq 9 | sed '/^3/,/7/d'
1
2
8
9

It will get my 7 deleted but I want to preserve it.

To be more precise, I can accurately locate MarkA (e.g. ^3), but I want to delete up to the first MarkB. I.e.,

seq 19 | sed '/^3/,/7/d'

is what I'm looking for if the 7 line is not deleted.

4

2 Answers

Using sed

This deletes the range up to but not including the last line in the range:

$ seq 9 | sed '/^3/,/7/{/7/p;d}'
1
2
7
8
9

As before, /^3/,/7/ selects the whole range, inclusive of /7/. And, as before, that range gets deleted with the d command. However, before we delete, we check to see if the line contains /7/ and, in that case, we print it with the p command.

Using awk

awk offers much flexibility. Here, we use a variable f as a flag to decide if lines should be printed:

$ seq 9 | awk '/^3/{f=1} /7/{f=0} !f'
1
2
7
8
9

You could use sed's predecessor, ed, if you have the data in a file:

seq 9 > data
printf '%s\n' '/^3/,/7/-1 d' 'wq' | ed -s data
cat data
1
2
7
8
9

The command breaks down like this:

  • printf -- send two strings down the pipe; those two strings have a newline appended to them so that they appear as commands to ed. The two commands are:
    • /^3/,/7/-1 d -- in the range /^3/ to one before /7/, delete the lines
    • wq -- write the file back to disk and quit
  • ed -s data -- run ed in silent mode, so that it does not report the number of bytes written at the end.

The core useful feature here is ed's ability to use addition or subtraction after the range regular expression. The (GNU) ed manpage describes it here:

A line address is constructed as follows:

...

Addresses can be followed by one or more address offsets, optionally separated by whitespace. Offsets are constructed as follows:

'+' or '-' followed by a number adds or subtracts the indicated number of lines to or from the address.

'+' or '-' not followed by a number adds or subtracts 1 to or from the address.

A number adds the indicated number of lines to the address.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like