1

I want to do the same as in

Extract lines between two patterns from a file

but I want to not have the line with the ending printed. Now, I could grep the results of the solutions to that question, I suppose - but can I, instead, make the sed or the awk solutions there use some kind of lookahead to not print the line matching the ending pattern?

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • For a moment I missed that this is a perfect duplicate! I recommend to at least try to google the headline of your intended question before clicking the submit button. ;) – hek2mgl Jan 08 '17 at 12:08
  • @hek2mgl: I actually did do some googling, but that got me the related non-dupe... – einpoklum Jan 08 '17 at 12:27
  • 1
    No worries, I hope the answers in that thread are helpful for you. – hek2mgl Jan 08 '17 at 13:14

2 Answers2

3

Like this:

sed -n '/begin/,/end/{/end/!p}'

That will print all lines in the range begin - end except of the line containing end itself from the output.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • This will potentially also exclude the first line, if it matches `end` as well. – Andreas Louv Jan 08 '17 at 11:59
  • 1
    @andlrc: I wasn't thinking about that, but - if that's the case, then my question is rather poorly defined. So that's fine by me I guess. – einpoklum Jan 08 '17 at 12:00
  • I agree, if the line containing `begin` also contains `end`, then the range borders would have been poorly chosen. – hek2mgl Jan 08 '17 at 12:01
  • @hek2mgl: just out of curiosity why does it don't give me the same out put when I use sed -e '/begin/,/end/{/end/d}' ? – Vicky Jan 08 '17 at 16:13
  • Because that would also print lines which are not part of the range – hek2mgl Jan 08 '17 at 17:45
  • @hek2mgl : yes but why so , Why does it give the lines that are not part of the range ? – Vicky Jan 09 '17 at 07:52
  • Because you are omitting `-n` . – hek2mgl Jan 09 '17 at 08:11
  • PS: If you want to restrict yourself to the `d` command it would be `sed '1,/begin/{/begin/!d};/end/,/begin/{/begin/!d}'` – hek2mgl Jan 09 '17 at 08:22
  • Actually I want to understand the difference between two commands sed -e '1,/begin/{/begin/d}' and sed -n '1,/begin/{/begin/p}' sed -e '1,/begin/{/begin/d}' also brings the output beyond the range (lines after begin also printed in output ) but and sed -n '1,/begin/{/begin/p}' brings the output with in the range (lines between 1 and begin) How is the range being irrelevant with d ? shouldn't sed -e '1,/begin/{/begin/d}' discard what's beyond the range specified ? – Vicky Jan 09 '17 at 11:34
  • I've explained that to you. Probably you are missing the fact that sed will print all lines by default unless `-n` has been passed on the command line. – hek2mgl Jan 09 '17 at 12:28
1

Using awk one can control it easily:

$ awk '/begin/{p=1};/end/{p=0};p' input

Breakdown:

/begin/{p=1} # When current line matches `begin' then set p = 1
/end/{p=0}   # When current line matches `end' then set p = 0
p            # Print lines when p is truly, in this case when it's 1.
             # `p' starts empty, and will later be set to 0, which
             # are both falsy values.
             # It's only in the state p = 1 that the lines are printed.

You might by now notice how you can move p around to get a different result i.e, to print lines between begin and end but not the lines it self:

p; /begin/{p=1}; /end/{p=0}
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123