1

How to delete all the lines between two pattern in file using .

Here pattern are //test and //endtest, file content:

blah blah blah
c
f
f
[
]
//test
all text to be deleted 
line1
line2
xyz
amv
{
//endtest
l
dsf
dsfs

Expected result:

blah blah blah
c
f
f
[
]
//test
//endtest
l
dsf
dsfs
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137
  • see also [How to select lines between two patterns?](https://stackoverflow.com/questions/38972736/how-to-select-lines-between-two-patterns/) – Sundeep Apr 17 '19 at 08:05
  • If `awk` is a viable alternative for you you should checkout this answer I wrote some time ago: https://stackoverflow.com/a/31112076/42580 – UlfR Apr 17 '19 at 12:26
  • 1
    Don't use range expressions as they make trivial tasks very slightly briefer but then require a complete rewrite or duplicate code when your requirements change in the slightest (e.g. to test some value inside the range or include/exclude the range start/end lines). Use a flag variable instead. Since sed doesn't have variables that means you shouldn't use sed for tasks like this, just use awk instead, see for example https://stackoverflow.com/a/55721516/1745001. – Ed Morton Apr 17 '19 at 13:29

3 Answers3

3

This is common feature of sed

 sed '/^\/\/test$/,/^\/\/endtest/d'

As / is used to bound regex, they have to be escaped, in regex.

If you want to keep marks (as requested):

sed '/^\/\/test$/,/^\/\/endtest/{//!d}'

Explanation:

Have a look at info sed, search for sed address -> Regexp Addresses and Range Addresses.

Enclosed by { ... }, symbol // mean any bound.

The empty regular expression '//' repeats the last regular expression match (the same holds if the empty regular expression is passed to the 's' command).

! mean not, then d for delete line

Alternative: You could write:

sed '/^\/\/\(end\)\?test$/,//{//!d}' 

or

sed -E '/^\/\/(end)?test$/,//{//!d}'

Will work same, but care, this could reverse effect if some extra pattern //endtest may exist before first open pattern (//test).

... All this was done, using GNU sed 4.4!

Under MacOS, BSD sed

Under MacOS, I've successfully dropped wanted lines with this syntax:

sed '/^\/\/test$/,/^\/\/endtest/{/^\/\/\(end\)\{0,1\}test$/!d;}'

or

sed -E '/^\/\/test$/,/^\/\/endtest/{/^\/\/(end)?test$/!d;}'
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137
2

With awk:

$ awk '/\/\/endtest/{p=0} !p; /\/\/test/{p = 1}' file
blah blah blah
c
f
f
[
]
//test
//endtest
l
dsf
dsfs
user000001
  • 32,226
  • 12
  • 81
  • 108
  • 1
    You should delete your answer as it was clearly written that the solution should be solved with sed. Or? – YesThatIsMyName Apr 17 '19 at 06:59
  • @YesThatIsMyName no, the question was edited after I answered – user000001 Apr 17 '19 at 07:01
  • 1
    Then you will recieve 1UP from me :-D – YesThatIsMyName Apr 17 '19 at 07:02
  • 1
    @YesThatIsMyName people often post questions asking for an answer in some specific tool just because they don't know any better. Restricting answers to just the tool they asked for (unless they're very specific that they can ONLY use that tool) while there's a better solution using some other tool isn't useful. In this case sed and awk are both standard tools that exist in every UNIX installation and people often get confused about which of them to use for which task so it's very common for people to ask for a solution in 1 and accept a solution in the other. – Ed Morton Apr 17 '19 at 13:26
  • @EdMorton Thanks for the detailed explanation. – YesThatIsMyName Apr 17 '19 at 13:49
0

if your data in 'd' file, try gnu sed:

sed -E '/\/\/test/,/\/\/endtest/{/\/\/.*test/!d}' d