How can I replace a pattern only on lines that do or do not contain another pattern?
To replace "blue" with "green" in lines that contain "red":
:g/red/s/blue/green
To do the replacement in lines that do not contain "red":
:g!/red/s/blue/green
Use Pattern-Match Addresses
Just as in sed, you can use a pattern for the addresses on which to operate. For example, given the following file:
foo bar
bar
foo bar baz
bar baz
quux bar
You would issue a command like the following:
:g/^foo/s/bar/foobarbaz/g
Explanation
This will tell Vim to apply the pattern match only to each line that starts with "foo" and to perform the replacement on multiple matches within each matching line. So, even though "bar" appears on multiple lines, with this invocation you will end up with the following output:
foo foobarbaz
bar
foo foobarbaz baz
bar baz
quux bar
Note that only the lines that start with "foo" at the beginning of the line will be matched, so lines with "bar" on the other lines remain untouched.