How to repeat the same search and replace command over disjunct line ranges in Vim?
replace, vim
Solution
If you need to perform a set of line-wise operations (like substitutions) on a bunch of different ranges of lines, one trick you can use is to make those lines look different by first adding a prefix (that isn't shared by any of the other lines).
The way I usually do this is to indent the entire file with something like `>G` performed on the first line, and then use either `:s/^ /X/` commands or block-visual to replace the leading spaces with X on the lines I want.
Then use `:g` in conjunction with `:s`. eg:
:%g/^X/s/FOO/BAR/g
:%g/^X/s/BAZ/QUUX/g
Finally, remove the temporary prefixes.
Problem
I had a situation where I wanted to replace `FOO` with `BAR` through out a file. However, I only want to do it in certain places, say, between lines 68–104, 500–537, and 1044–1195. In practice, I dropped markers at the lines of interest (via `ma`, `mb`, `mc`, etc.) and ran the following: ``` :'a,'b s/FOO/BAR/g | 'c,'d s/FOO/BAR/g | 'e,'f s/FOO/BAR/g ``` I had to repeat this dozens of times with different search and replace terms `s/CAT/DOG`, etc., and it became a pain to have to rewrite the command line each time. I was lucky in that I had only three places that I needed to confine my search to (imagine how messy the command line would get if there were 30 or 40). Short of writing a function, is there any neater way of doing this? On a related note. I copied `FOO` to the `s` (search) register, and `BAR` to the `r` (replace) and tried running ``` :'a,'b s/\=@s/\=@r/ | 'c,'d s/\=@s/\=@r/ | 'e,'f s/\=@s/\=@r/ ``` This would have saved me having to rewrite the command line each time, but, alas, it didn’t work. The replace bit `\=@r` was fine, but the `\=@s` bit in the search pattern gave me an error. Any tips would be appreciated.