Reputation: 2382
I have a file with this in it:
test
Test
Currently, if If I want to replace all cases of 'test' with 'foo', and 'Test' with 'Foo', I have to use two commands:
:%s/test/foo/g
:%s/Test/Foo/g
Is there any way that I can accomplish this with a single command?
Upvotes: 36
Views: 12455
Reputation: 2436
As my granpappy used to say, for every plugin there's a vim one-liner that's just as good. Try
%s/\(test\|Test\)/\=submatch(0) =~ '^\l.*' ? 'foo' : 'Foo'/g
Explanation:
%s/
substitute over the whole buffer
\(test\|Test\)/
match for 'test' OR 'Test'
\=
Make the substitute string use whatever the following expression evaluates to
submatch(0)
In this context evaluates to the entire matched expression
=~ '\l.*'
String-comparison for regex match (against a word starting with a lowercase letter)
... ? 'foo' : 'Foo'
if-then-else expression which evaluates to 'foo' if ... is true, 'Foo' otherwise
/g
Do this over the entire line
With slight modifications this should be more than enough to satisfy our needs. References:
:help :s
:help :sub-replace-\=
:help expression
...I just want to put a little warning for anyone who tries to get into vim evaluations and expressions... They are very counter-intuitive (I come from a C++ background, maybe if you come from bash or python it's less of an issue). I found the following vimscript guide/ self-teaching lessons to be extremely helpful: http://learnvimscriptthehardway.stevelosh.com/
Upvotes: 15
Reputation: 15967
I think this vim plugin by tim pope will solve your problem, install it and
%Subvert/{t}est/{f}oo/g
or %Subvert/test/foo/g
(thanks for the comment) will do the trick
Upvotes: 16