EDIT Here is a better solution than the one I gave previously:
'<,'>g/.*/norm! $4hCfoo
'<,'>
apply the command to the visual selection
g/.*/
apply the global command on all the lines (of the visual selection)
norm!
interpret the following string as a normal command
$4hCfoo
go 4 characters before the end of the line and replace them by foo
EDIT 2 And another one for the fun:
'<,'>g/.*/execute "s/\\%" . (len(getline('.'))-4) . "c.*$/toto"
I think it is overcomplicated but is interesting to understand the behavior of the global command:
'<,'>
Apply on the visual selection
g/.*/
Apply the global command on all the lines of the visual selection
execute "..."
Execute the following string as a command (We use it to insert a calculation)
s/
Aplly a substitution on the following pattern
\\%"
Beginning of the pattern of the form \%Xc.*$
i.e. from the Xth column to the end of the line
. (len(getline('.'))-4) .
Calculate the number of the column based on the size of the line minus the number of column to change
"c.*$
end of the pattern
"toto"
The string to use as replacement
The interesting part is that to be able to use . (len(getline('.'))-4) .
in the substitution you have to use the global command:
The global command will execute the command on each selected lines one after one, so getline('.')
is updated on each line. If you only used
execute "'<,'>s/\\%" . (len(getline('.'))-4) . "c.*$/toto"
The getline('.')
would only be the current line and thus you would get unexpected results.
There are probably some better solutions but you could do it using a macro. For example to replace the last 4 characters by foo
:
qa$4hCfoo<Esc>jq
qa
record a macro
$4h
go 4 character before the end of the line
C
remove the end of the line and enter insert mode
foo
the text to insert
<Esc>
leave insert mode
j
go to the next line
q
stop recording the macro
You can then go to the first line and use 5@a
to apply the macro on the 5 next lines.