Question

:s/u/X/2 - this replaces the first u to X on the current and next line...

or to replace the second character on a line with X???? IDK.

or perhaps its something other than :s?

I suspect I have to use grouping of some kind (\2?) but I don't know to write that.

I heard that sed and :s option in sed are alike, and on a help page for sed I found:

3.1.3. Substitution switches:

Standard versions of sed support 4 main flags or switches which may be added to
the end of an "s///" command. They are:

   N      - Replace the Nth match of the pattern on the LHS, where
            N is an integer between 1 and 512. If N is omitted,
            the default is to replace the first match only.
   g      - Global replace of all matches to the pattern.
   p      - Print the results to stdout, even if -n switch is used.
   w file - Write the pattern space to 'file' if a replacement was
            done. If the file already exists when the script is
            executed, it is overwritten. During script execution,
            w appends to the file for each match.

http://sed.sourceforge.net/sedfaq3.html#s3.1.3

so: :r! sed 's/u/X/2' would work, although I think there is a specifically vi way of doing this?

IDK if its relevant but I'm using the tcsh shell.

also, :version: Version 1.79 (10/23/96) The CSRG, University of California, Berkeley.

Was it helpful?

Solution

This is brittle, but may be enough to do what you want. This switch command with regex:

:%s/first\(.\{-}\)first/first\1second/g

converts this:

first and first then first again
first and first then first again
first and first then first again
first and first then first again

to this:

first and second then first again
first and second then first again
first and second then first again
first and second then first again

The regexp looks for the first "first", followed by a match of any characters using pattern .\{-}, which is the non-greedy version of .* (type :help non-greedy in vim for more info.) This non-greedy match is followed with the second "first".

The characters between the first and second "first" are captured by surrounding the .\{-} with parenthesis, which, with escaping results in \(.\{-}\), then that captured group is dereferenced with the \1 (1 means first captured group) in the replacement.

OTHER TIPS

In order to substitute the second occurrence on a line, you can say:

:call feedkeys('nyq') | s/u/X/gc

In order to invoke it over a range of lines or the entire file, use it in a function:

:function Mysub()
:  call feedkeys('nyq') | s/u/X/gc
:endfunction

For example, the following would substitute the second occurrence of u for X in every line in the file:

:1,$ call Mysub()

Here's a dumber but easier to understand way: first find a string that doesn't exist in the file - for the sake of argument assume it's zzz. then simply:

:%s/first/zzz
:%s/first/second
:%s/zzz/first
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top