On Thu, Apr 20, 2006 at 10:37:35PM -0500, Chris Gordon wrote:
> I'm working in a unix environment where only VI is available, not VIM.
>  I am trying to get a regular expression to basically do a find and
> replace in several files that spans several lines. I have googled it
> and can't find much.  \n seems to be what I remember, as well as what
> I have found in various pages, but it doesn't work.
> 
> For example I would like to replace
> 
> line1
> line2
> 
> with
> 
> line1
> addline3
> line2
> 
> and I try
> :%s/line1\nline2/line1\naddline3\nline2/g
> I've even tried just searching for it.
> /line1\nline2
> 
> nothing seems to work.
> 
> Does anyone know how I can do this (don't feel limited to vi, I've
> tried ed and sed and can't get the syntax correct on those either)?

First I sat down with nvi (bug-for-bug compatible).  I don't
remember ever getting multiline matches to work.  This kind of
search is successful:

:%s/line1/line1^V^Mnew/

This just appends "new" after "line1".

What you really want is sed, and a little browsing online
confirms it.  You need to use a multiline pattern space.

$ cat > test.file <<END
line1
line2
line1
line3
END

$ sed '/^line1$/{
N
s/\nline2$/\nnew\nline2/
}' < test.file
line1
new
line2
line1
line3

Explanation:  This is a multiline match.  When the pattern
/^line1$/ matches the buffer, then sed executes operator enclosed
in braces.  N adds another line to the "hold space" which means
we are now working on two consecutive lines instead of one line.
Then we replace from the line break to the end of the hold space
with new data.

It does what you describe.  Magic.

Just a caution...  It breaks on a file that looks like this:
line1
line1
line2

If your data is uniform "multiline records" then this probably
won't be a problem.  Otherwise, I think Perl would hold your best
solution.  You could read the whole file as one string (assuming
it fits in memory) and do the search+replace on the whole thing
at once.

Don

-- 
Don Bindner <[EMAIL PROTECTED]>

-----------------------------------------------------------------
To get off this list, send email to [EMAIL PROTECTED]
with Subject: unsubscribe
-----------------------------------------------------------------

Reply via email to