Hello! Small command, lots of power.
$ cat testcase2 some code // feature-x-start foo bar // feature-x-end more code
$ cat testcase2 | sed '\|// feature-x-start|,\|// feature-x-end|d' some code more code
How and why does this work?
Now the interesting part. Resources to learn from. https://catonmat.net/sed-one-liners-explained-part-three shows the foundation of this recipe and it calls it “Selective Deletion of Certain Lines”, specifically “Print all lines in the file except a section between two regular expressions.”.
It uses a feature that is called “range addresses” in the
An address range matches lines starting from where the first address matches, and continues until the second address matches (inclusively):
This clarifies that this always matches (whole) lines.
I have found other names for this
sed feature. Depending on what book/resource you’re looking at, this may be called “address range” or “pattern range” or “range match”.
This technique really has little or nothing to do with the sed substitute command which we’re most often using. The
d part of the recipe above? Well:
The ‘d’ command deletes the current pattern space
What about those
When using e.g.
s/foo/bar/g I am used to the idea that we can use a different delimiter so that we can easily add in a literal forward slash, like in
This doesn’t work naively with the pattern range. Does it? Internet forums are nice, the older the nicer. Waldner said in 2010 that “It just has to be escaped”. And that’s what the backslash is for.
This allows for using the forward slash in the pattern as I did in
sed '\|// feature-x-start|,\|// feature-x-end|d'
The following example demonstrates that indeed sed here operates in a line-based fashion, i.e. this selective deletion of lines does not work on line fragments:
$ cat testcase1 a test file with /Xtremely nice contents for your amusements.
$ cat testcase | sed '\|/Xtremely|,\|for|d' a test file amusements.
I used this in CI. Lots of love for sed.