Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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 
    bla
    end

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 sth like this: (?<=start).*(?=end)

This does not work because i guess i use the command line grep with 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?

share|improve this question

migrated from stackoverflow.com Nov 29 '11 at 15:06

This question came from our site for professional and enthusiast programmers.

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.

share|improve this answer

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.

share|improve this answer
    
What if i have multiple ["start" (.*) "end"] blocks in the file and i want to treat them later on seperately? –  curious Nov 29 '11 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 '11 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 '11 at 9:04
    
@curious: You're right. I was also wrong about the match being greedy. –  flesk Nov 29 '11 at 9:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.