UPDATE
So I have found simpler solution:
:/first/,/second/g/bar/s/foo/bar/g
/first/,/second/
take a range between first
and second
g/bar/
filter out lines that do not have bar
(keep lines that has bar
s)
s/foo/bar/g
substitute all foo
s with bar
s 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
- range from
first
to second
- substitute
foo
s 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
g
flag?:%s/foo/bar
(or with theg
flag to replace all of the occurrences)