1

The following search command will make a range and search/replace within it. Specifically, it looks for 'first' in the text, then stops when it finds 'second' across multiple lines. Then, within that range of selected things, it will replace foo with bar. What I'm not sure how to do is to replace all occurrences of foo on each line with bar. I've tried using /%s/ instead of /s/ What am I missing?

:/first/;/second/s/foo/bar
  • 3
    not sure I understand, but don't you just need the g flag? – Christian Brabandt Oct 24 '18 at 8:36
  • 1
    I think the syntax you're looking for is :%s/foo/bar (or with the g flag to replace all of the occurrences) – statox Oct 24 '18 at 8:43
  • Nope %s doesn't work. – cmaughan Oct 25 '18 at 14:39
  • Note: One way to achieve the above would be to keep running the command until all cases of foo on the same line were replaced..... – cmaughan Oct 25 '18 at 14:40
  • I would suggest to emphasize part of the phrase "to replace all occurrences of foo on each line with bar" – Maxim Kim Oct 25 '18 at 15:34
2

UPDATE

So I have found simpler solution:

:/first/,/second/g/bar/s/foo/bar/g
  1. /first/,/second/ take a range between first and second
  2. g/bar/ filter out lines that do not have bar (keep lines that has bars)
  3. s/foo/bar/g substitute all foos with bars within filtered lines.

Old solution

It is kind of tricky and probably would be much easier if :g command could be used recursively with the ranges. But it can't.

You can try the following:

:/first/,/second/s/\(bar.*\zsfoo\ze\)\|\(\zsfoo\ze .*bar\)/bar/g
  1. range from first to second
  2. substitute foos only if the line has bar before foo or after foo

I have tested it with the following:

foo bar foo bar bar

first
foo bar foo bar bar
hello foo foo world
hello foo hlkj sdklfj bar fooworld
foo bar foo bar bar
foo bar foo bar bar
second

foo bar foo bar bar
foo bar foo bar bar
foo bar foo bar bar

After the substitution:

foo bar foo bar bar

first
bar bar bar bar bar
hello foo foo world
hello bar hlkj sdklfj bar barworld
bar bar bar bar bar
bar bar bar bar bar
second

foo bar foo bar bar
foo bar foo bar bar
foo bar foo bar bar
  • That's a pretty nasty solution! But it's a solution none the less.... ;) I was hoping for something simpler.... – cmaughan Oct 25 '18 at 14:38
  • @cmaughan I’m confused. You comment under my answer that you want every foo replaced with bar, but this is not what this answer does (or is intended to do). Could you clarify exactly what you mean? Perhaps with a before and after of an example file? – Rich Oct 25 '18 at 15:01
  • @cmaughan check the updated version of the answer -- it is way simpler – Maxim Kim Oct 25 '18 at 15:31
  • @MaximKim Your simpler solution does the right thing, though I think your afterwards substitution has 2 'foo' in it that are also correctly changed using your approach; I get all foo's between first and second converted to 'bar', which is what I wanted :) – cmaughan Oct 25 '18 at 15:37
  • 1
    @cmaughan the thing is -- you question is very hard to understand. Basically I can read it the way the answer :/first/,/second/s/foo/bar/g will be correct. It will replace all foos with bars on each line between first and second. My current answer on the other hand works slightly different. It does replacement between said range but only on lines that have bars. – Maxim Kim Oct 25 '18 at 15:44
0

As @ChristianBrabandt mentioned in a comment, you need to use the g flag to the :substitute command:

:/first/;/second/s/foo/bar/g

See :h :s_flags for details on this and other flags you can use with :s commands.

  • He wants: > to replace all occurrences of foo on each line with bar – Maxim Kim Oct 24 '18 at 13:53
  • 1
    @MaximKim Yes. You’re reading that as meaning they only want the replacements to occur on lines that contain the text bar. I think what the OP actually means is that they want every foo replaced with bar (on every line). – Rich Oct 24 '18 at 19:31
  • Yes, that's right - every foo with bar on every line. s/ (and %s/) don't do this. And adding g doesn't either. – cmaughan Oct 25 '18 at 14:37
  • @cmaughan That’s odd. It works in my testing. Could you give an example of a file where it doesn’t work for you? – Rich Oct 25 '18 at 14:59
  • Now I read the question once again and a little bit confused. – Maxim Kim Oct 25 '18 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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