:/baa/,/quz/s/baa/bar/
works, but that will only work with the first occurrence of baa
. If you want to replace all occurrences of baa
with bar
that come before quz
:
,/quz/s/baa/bar
If your scenario calls for replacing all occurrences of baa
if quz
is found:
/quz/,%s/baa/bar
That will replace all occurrences of baa
with bar
if quz
is found. This is basically using the range /quz/,1,$
which is permitted (%
is equivalent to 1,$
).
From :h cmdline-ranges
If more line specifiers are given than required for the command, the first one(s) will be ignored.
So if the first line specifier /quz/
fails, it generates an error and causes the rest of the command to not execute. But, if it does find a match, the 1,$
range is used since substitution only needs 2 range specifiers.
Conditional substitution
If you want to conditionally replace baa
with bar
, you'll want to use the :global
command.
If you want replace baa
with bar
if it comes before quz
:
:g/quz/?baa?,s//bar
Explanation:
g/quz/ - Moves to the next 'quz'
?baa?, - Create a range from the last 'baa' to the current line
s//bar - Reuse the previous pattern (baa) and substitute with 'bar'
However, that only matches the first baa
that comes before quz
.
If you want to replace all occurrences of baa
that comes before quz
:
g/quz/?quz\|\%^?,s/baa/bar
Explanation:
g/quz/ - Moves to the next 'quz'
?quz\|\%^?, - Create a range from the previous 'quz' or the
beginning of the buffer.
s/baa/bar - Replace 'baa' with 'bar'
If you want to replace all occurrences of baa
with bar
if they're between two quz
lines:
g/quz/silent! ??,s/baa/bar
Explanation:
g/quz/ - Moves to the next 'quz'
silent! - The first occurence of 'quz' won't have a previous
'quz' match. So, ignore the error about an invalid
range.
??, - Reuse 'quz' pattern to search for the previous occurrence
s/baa/bar - Replace 'baa' with 'bar'