Global substitute

4 views
Skip to first unread message

Robert Mark Bram

unread,
Dec 13, 2008, 7:22:04 PM12/13/08
to vim_use
Hi All,

I am having trouble getting this global find and replace to work:

:%s/\(<\/\+p>\)/^M\1^M/g

Simply, it is only replacing the first instance on each line.. can
anyone guide me as to what I am doing wrong?

Thanks for any assistance!

Rob
:)

Tim Chase

unread,
Dec 13, 2008, 7:44:00 PM12/13/08
to vim...@googlegroups.com
> I am having trouble getting this global find and replace to work:
>
> :%s/\(<\/\+p>\)/^M\1^M/g
>
> Simply, it is only replacing the first instance on each line.. can
> anyone guide me as to what I am doing wrong?


The regexp does indeed replace every instance on each line, but I
think it may not be finding the quite the pattern you think
you're looking for. Your pattern finds

</p>
<//p>
<////p>

but not

<p>

thanks to your \+ requiring one or more "/" characters. I
suspect you may be wanting \= instead.

Alternatively, if you have literal "caret capital-M", instead of
a literal control+M (as entered with "control+V control-M), you
might use "\r" instead of the "^M".

-tim

Robert Mark Bram

unread,
Dec 13, 2008, 8:57:02 PM12/13/08
to vim_use
Thanks Tim,

> > :%s/\(<\/\+p>\)/^M\1^M/g
>
> > Simply, it is only replacing the first instance on each line.. can
>
> thanks to your \+ requiring one or more "/" characters. I
> suspect you may be wanting \= instead.

It was that.. plus I had this setting in my .vimrc:

" assume the /g flag on :s substitutions to replace all matches in a
line:
set gdefault


So all I needed was this:
:%s/\(<\/\=p>\)/^M\1^M/

> Alternatively, if you have literal "caret capital-M", instead of
> a literal control+M (as entered with "control+V control-M), you
> might use "\r" instead of the "^M".

Btw, I mad the ^M with control+V, ENTER. I thought that was the (a?)
correct way to get a new line character in the replace section of a
sed.

Rob
:)

Tim Chase

unread,
Dec 13, 2008, 9:19:22 PM12/13/08
to vim...@googlegroups.com
>> Alternatively, if you have literal "caret capital-M", instead of
>> a literal control+M (as entered with "control+V control-M), you
>> might use "\r" instead of the "^M".
>
> Btw, I mad the ^M with control+V, ENTER. I thought that was the (a?)
> correct way to get a new line character in the replace section of a
> sed.

Yes, either will do -- however when all we've got is plain-text
emails to communicate, it's hard to discern "^M" (the two
characters "caret em") from "^M" (a single control+M character
displayed in Vim with an alternate color and entered by prefixing
with control+V which, for those sourcing the accursed mswin.vim,
becomes some other character like control+Q which then has to be
further clarified). Given the complications involved, I tend to
just use the "\r" notation to make it as unambiguous as possible. :)

But when I'm vimming personally, I use them both interchangeably
with equal frequency.

-tim


Tony Mechelynck

unread,
Dec 13, 2008, 9:20:43 PM12/13/08
to vim...@googlegroups.com
On 14/12/08 02:57, Robert Mark Bram wrote:
> Thanks Tim,
>
>>> :%s/\(<\/\+p>\)/^M\1^M/g
>>> Simply, it is only replacing the first instance on each line.. can
>> thanks to your \+ requiring one or more "/" characters. I
>> suspect you may be wanting \= instead.
>
> It was that.. plus I had this setting in my .vimrc:
>
> " assume the /g flag on :s substitutions to replace all matches in a
> line:
> set gdefault

Yeah, I set that at one time in the past but I came back from it.

>
>
> So all I needed was this:
> :%s/\(<\/\=p>\)/^M\1^M/
>
>> Alternatively, if you have literal "caret capital-M", instead of
>> a literal control+M (as entered with "control+V control-M), you
>> might use "\r" instead of the "^M".
>
> Btw, I mad the ^M with control+V, ENTER. I thought that was the (a?)
> correct way to get a new line character in the replace section of a
> sed.

It is one correct way, but neither the simplest nor the easiest (in Vim,
I'm not talking about sed, which I haven't really studied yet). In the
replace-by part of a ":s[ubstitute]" command, \r breaks the line (but in
a search pattern, or in the replace-what? part, \n finds a linebreak).
In a ":map" command (or one of its variants), <CR> (4 characters)
corresponds to a press on the Enter key (reacts to it in the {lhs}, or
simulates it in the {rhs}). In a double-quoted string, "\r" represents a
carriage-return control character (ASCII 0x0D). In all these cases
(except where I mentioned \n), using the ctrl-V method to enter a
literal ctrl-M is valid but not practical.

>
> Rob
> :)

Best regards,
Tony.
--
"According to the Rand McNally Places-Rated Almanac, the best place to
live in America is the city of Pittsburgh. The city of New York came
in twenty-fifth. Here in New York we really don't care too much.
Because we know that we could beat up their city anytime."
-- David Letterman

Matt Wozniski

unread,
Dec 13, 2008, 9:29:44 PM12/13/08
to vim...@googlegroups.com
On Sat, Dec 13, 2008 at 9:20 PM, Tony Mechelynck wrote:
>
> On 14/12/08 02:57, Robert Mark Bram wrote:
>> Thanks Tim,
>>
>>>> :%s/\(<\/\+p>\)/^M\1^M/g
>>>> Simply, it is only replacing the first instance on each line.. can
>>> thanks to your \+ requiring one or more "/" characters. I
>>> suspect you may be wanting \= instead.
>>
>> It was that.. plus I had this setting in my .vimrc:
>>
>> " assume the /g flag on :s substitutions to replace all matches in a
>> line:
>> set gdefault
>
> Yeah, I set that at one time in the past but I came back from it.
>
>>
>>
>> So all I needed was this:
>> :%s/\(<\/\=p>\)/^M\1^M/
>>
>>> Alternatively, if you have literal "caret capital-M", instead of
>>> a literal control+M (as entered with "control+V control-M), you
>>> might use "\r" instead of the "^M".
>>
>> Btw, I mad the ^M with control+V, ENTER. I thought that was the (a?)
>> correct way to get a new line character in the replace section of a
>> sed.
>
> It is one correct way, but neither the simplest nor the easiest (in Vim,
> I'm not talking about sed, which I haven't really studied yet).

FWIW, you can use \n in sed.

echo a | sed 's/a/a\nb\n/'

is equivalent to

:s/a\n/a\rb\r/

~Matt

Christian Ebert

unread,
Dec 14, 2008, 7:07:25 AM12/14/08
to vim...@googlegroups.com
* Matt Wozniski on Saturday, December 13, 2008 at 21:29:44 -0500

> FWIW, you can use \n in sed.

That depends on the implementation.


>
> echo a | sed 's/a/a\nb\n/'
>
> is equivalent to
>
> :s/a\n/a\rb\r/

/sw/bin/sed == GNU, /usr/bin/sed == Apple shipped BSD-like


~$ echo a | /sw/bin/sed -e 's/a/a\nb\n/'
a
b

~$ echo a | /usr/bin/sed -e 's/a/a\nb\n/'
anbn


Workaround (too lazy to look up the credits):

~$ echo a | /usr/bin/sed -e 's/a/a\'$'\n''b\'$'\n''/'
a
b


c
--
\black\trash movie _C O W B O Y_ _C A N O E_ _C O M A_
Ein deutscher Western/A German Western
-->> http://www.blacktrash.org/underdogma/ccc.html
-->> http://www.blacktrash.org/underdogma/ccc-en.html

Reply all
Reply to author
Forward
0 new messages