I want to match everything that is between some lines with regexp but not this that match the start and the end. This sound to me as positive lookbehind and positive lookahead

    start text
    bla bla 

There are multiple number of this kind of blocks so I would like to extract all this blocks and then for each of these blocks I would like to extract something based on a different regexp. So it should be something like:

match start 
then match everything until the first occurrence of end
match start 
then match everything until the first occurrence of end

and so on...

so I made something like this: (?<=start).*(?=end)

This does not work because I guess I use the command line grep, which treats the file as a set of lines and tries to apply the regex in every single line. Is there any way to treat the file as a whole line or this is not a good solution and I have to use a combination of various command line tools like extracting the text with sed and then build a file whose lines contains the concatenation of various lines from the initial file?

  • I tried with grep -P -o -z -e '(?<=start)((.|\n)*?)(?=end)' and its output seems fine.
    – nxnev
    Aug 31, 2017 at 11:07

2 Answers 2


Since a'r beat me to the sed solution, I'll just post the perl equivalent:

perl -ne 'print if/start/../end/'

It's a bit more verbose though.


You may find sed easier in this case.

sed -ne '/start/,/end/p'

An alternative sed expression that concatenates the matched lines together:

sed -ne '/start/ba; be;' \
     -e ':a; N; /end/{s/\n/ /g; p; be;}; ba' \
     -e :e

The first section branches to label a if the line matches /start/, otherwise branches to e (the end).

The second section loops through lines appending them to the pattern space until a line matching /end/ is found, when it replaces the new lines with spaces, prints the line and then branches to e (the end).

The third section merely provides the label e.

  • What if i have multiple ["start" (.*) "end"] blocks in the file and i want to treat them later on seperately?
    – curious
    Nov 29, 2011 at 8:46
  • @curious: You can nest multiple expressions like sed -ne '/start/,/end/p' -e '/next start/,/next end/' and write the result to a file with > myfile.txt after the sed command. You should notice that those ranges are greedy though, so you might match more than you intended if you have multiple similar lines.
    – flesk
    Nov 29, 2011 at 9:02
  • 1
    @flesk this does not work because with the first sed -ne '/start/,/end/p' it matches the first start until the last end. And also this isnot dynamic and generic.I do not know how many start-end blocks they consist in the file.The start and end is always the same patter
    – curious
    Nov 29, 2011 at 9:04
  • @curious: You're right. I was also wrong about the match being greedy.
    – flesk
    Nov 29, 2011 at 9:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .