169

In Vim, I have the following text:

key => value1
key => value2
key => value1111
key => value12
key => value1122222

I would like to add "," at the end of each line. The previous text will become the following:

key => value1,
key => value2,
key => value1111,
key => value12,
key => value1122222,

Does anyone know how to do this? Is it possible to use visual block mode to accomplish this?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
Grace Huang
  • 5,355
  • 5
  • 30
  • 52
  • Similar question [here](http://stackoverflow.com/questions/594448/how-can-i-add-to-the-end-of-each-line-in-vim). – glts Jul 03 '12 at 11:47

9 Answers9

233

This will do it to every line in the file:

:%s/$/,/

If you want to do a subset of lines instead of the whole file, you can specify them in place of the %.

One way is to do a visual select and then type the :. It will fill in :'<,'> for you, then you type the rest of it (Notice you only need to add s/$/,/)

:'<,'>s/$/,/
Alan Curry
  • 14,255
  • 3
  • 32
  • 33
204

There is in fact a way to do this using Visual block mode. Simply pressing $A in Visual block mode appends to the end of all lines in the selection. The appended text will appear on all lines as soon as you press Esc.

So this is a possible solution:

vip<C-V>$A,<Esc>

That is, in Normal mode, Visual select a paragraph vip, switch to Visual block mode CTRLV, append to all lines $A a comma ,, then press Esc to confirm.

The documentation is at :h v_b_A. There is even an illustration of how it works in the examples section: :h v_b_A_example.

glts
  • 21,808
  • 12
  • 73
  • 94
  • 1
    No, this is standard Vim: Select some lines in Visual block mode (with `C-V`) then move the cursor to the end of the line `$` and append to all of them `A`. You'll love [`:h v_b_A`](http://vimdoc.sourceforge.net/htmldoc/visual.html#v_b_A), which is really thorough. – glts Jul 04 '12 at 08:57
  • 1
    Oh, I see what's going on! I usually use Ctrl-C instead of to exit insert mode, and apparently with Ctrl-C this doesn't work! How odd. – weronika Jul 04 '12 at 18:04
  • 3
    You can save a keystroke by using `ip` in place of `vip`. – Aaron Thoma Mar 30 '14 at 22:38
  • 1
    @accolade, doesn't go into visual block mode that way, and won't work. needs to happen after again if you do it that way. – imagineerThat Dec 24 '15 at 06:14
  • @imagineerThat, weird - it works for me - must be due to some non-default option. (Not [`'virtualedit'`](http://vimdoc.sourceforge.net/htmldoc/options.html#'virtualedit') - I tested that.) I confirm that it doesn't work in a clean vim. Thanks for the note! – Aaron Thoma Dec 24 '15 at 11:50
  • For me what works is `(move the cursor to select any caracter of each afected line)$A,` Note the downcase of **v** – ivanxuu Sep 08 '16 at 14:44
  • Why is it necessary to use a `$`? If `A` appends at the end of a line when editing a single, then why does this not work: `vipA,` ? – Noel Evans Jun 06 '19 at 19:54
  • 1
    @NoelEvans because `vip` places the cursor at the bottom left corner of the selection and `A` has no special meaning for visual modes (check with `:vmap A`). it doesn't appear to be possible to move the cursor to a right side edge with `o` or `O` as they only function for visual block mode and `vip` does not produce a block selection (see `:h v_o`). that still probably wouldn't suffice except for in the case that one corner is longer than all the rest. – pkfm Oct 03 '20 at 20:24
  • 1
    @NoelEvans you can map `A` to `$A` in visual block mode but retain its meaning for all other visual modes via `vnoremap A mode()=~'\cv' ? 'A' : '$A'`. this works well for certain text objects like `ip` but not for others like `ap`. the drawback is that it would then be difficult to insert a column via visual block mode though this may be an irrelevant use case to you. – pkfm Oct 03 '20 at 20:25
  • Worked perfectly for me, IMHO this should be the accepted answer. – Tobias Gierke Jan 15 '21 at 16:04
52

Another solution, using another great feature:

:'<,'>norm A,

See :help :normal.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • 1
    @Swiss, you will like [this comment](http://stackoverflow.com/questions/11303032/how-to-add-text-at-the-end-of-the-each-line-in-vim/11305004#comment14879144_11306510), then. – romainl Jul 03 '12 at 08:48
  • 1
    @Swiss, you might also like [udioca's exposé](http://www.reddit.com/r/vimgolf/comments/wmtep/abusing_macros_part_1_normal/) on `:normal`. I found it informative! – Conner Jul 21 '12 at 20:52
  • 1
    Didn't know about this subreddit. Thanks. – romainl Jul 21 '12 at 21:02
50

ex mode is easiest:

:%s/$/,

: - enter command mode
% - for every line
s/ - substitute
$ - the end of the line
/ - and change it to
, - a comma
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
12

The substitute command can be applied to a visual selection. Make a visual block over the lines that you want to change, and type :, and notice that the command-line is initialized like this: :'<,'>. This means that the substitute command will operate on the visual selection, like so:

:'<,'>s/$/,/

And this is a substitution that should work for your example, assuming that you really want the comma at the end of each line as you've mentioned. If there are trailing spaces, then you may need to adjust the command accordingly:

:'<,'>s/\s*$/,/

This will replace any amount of whitespace preceding the end of the line with a comma, effectively removing trailing whitespace.

The same commands can operate on a range of lines, e.g. for the next 5 lines: :,+5s/$/,/, or for the entire buffer: :%s/$/,/.

pb2q
  • 58,613
  • 19
  • 146
  • 147
5
:%s/$/,/g

$ matches end of line

kalhartt
  • 3,999
  • 20
  • 25
4

If you want to add ',' at end of the lines starting with 'key', use:

:%s/key.*$/&,
romainl
  • 186,200
  • 21
  • 280
  • 313
kiddorails
  • 12,961
  • 2
  • 32
  • 41
3

I have <M-DOWN>(alt down arrow) mapped to <DOWN>. so that I can repeat the last command on a series of lines very quickly. with this mapping I can:

A,<ESC>

And then hold alt while pressing down repeatedly to append the comma to the end of each line.
This works well for me because it allows very good control over what lines do and do not get the change.
(I also have the other arrows mapped similarly to allow for easy repeating of .)

Here's the mapping line to paste into your vimrc:

map <M-DOWN> <DOWN>.
Aaron Thoma
  • 3,820
  • 1
  • 37
  • 34
Sam Brinck
  • 891
  • 1
  • 7
  • 11
2

Following Macro can also be used to accomplish your task.

qqA,^[0jq4@q
dvk317960
  • 672
  • 5
  • 10