0

I have a block of of text which contains variables whose name I want to change, but not all. I want to be able to choose which variables get replaced by the substitution and which do not. I tried using :%s/pattern/string/c, but the problem with that is that it starts from the beginning of the file, which also has the variables which I don't want to replace.

From :h :s:

:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
                        For each line in [range] replace a match of {pattern}
                        with {string}.
                        For the {pattern} see |pattern|.
                        {string} can be a literal string, or something
                        special; see |sub-replace-special|.
                        When [range] and [count] are omitted, replace in the
                        current line only.  When [count] is given, replace in
                        [count] lines, starting with the last line in [range].
                        When [range] is omitted start in the current line.

Specifically:

When [count] is given, replace in count] lines, starting with the last line in [range].
When [range] is omitted start in the current line.

My plan was to run the substitution once, then repeat it using & as many times as needed. However, if I do :s/pattern/string 1, unless the pattern exists in the current line, the substitution cannot find the pattern. I can only conclude I misunderstood the wording.

What is the best way to achieve what I want?

7
  • Using the c flag with a range doesn't work? E.g. 20,100s/pattern/string/c .... Also, do you have 'gdefault' set?
    – B Layer
    Jan 21, 2021 at 0:19
  • @BLayer It does, but I would want the process of defining the range. Just have the same functionality as that command starting from the current line onward. I don't have gdefault set.
    – daedsidog
    Jan 21, 2021 at 0:22
  • If you don't have 'gdefault' you should be using g flag, no? I'm not quite sure what you mean by "I would want the process of defining the range". The process?
    – B Layer
    Jan 21, 2021 at 1:13
  • @BLayer Sorry, that was a mistype on my end. I meant that I wanted to avoid range selection when doing this type of substitution. As far as I understand, the g flag controls if there should be only one substitution per line or more. In any case, both options don't work as I intend.
    – daedsidog
    Jan 21, 2021 at 1:28
  • Yes, that's what g does. I guess you're implying that you don't need to replace more than one word per line.
    – B Layer
    Jan 21, 2021 at 2:14

1 Answer 1

3

The default range for :substitute is ., the current line.

The simplest way to run a substitute that cannot fail is to use the e flag.

If you want to instead substitute the first occurrence after the cursor, I suggest

:/pattern/substitute//replace/flags

Alternately, if you really can't use :%substitute and you want behavior like the c flag, try searching /pattern, using cgn to put in the replacement, and then using n to navigate and . to repeat the change. (This is nice because, if you already know the next occurrence needs changed, you can skip the n and just press ..)

1
  • 1
    Thank you, this is exactly what I wanted. Playing around, I also notice it was possible to substitute the first line, then use n which finds the next pattern, and repeating the substitution for the line using &, but your alternative method is much quicker and intuitive.
    – daedsidog
    Jan 21, 2021 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.