Raj
Raj

Reputation: 3462

Vim Copy and paste text on the same line

I have an input text as follows -

(command (and (A B C) ))
(command (and (D E F) ))
(command (and (G H I) ))
...
...

I would like to copy and paste part of text on the same line as

(command (and (A B C) (A B C)))
(command (and (D E F) (D E F)))
(command (and (G H I) (G H I)))
...
...

Will it be possible to do it using VI Editor automatically?

Update : I think I missed one important point that the values A,B,C ... I... can have variable length. I just used them as symbols.

Thanks !

Upvotes: 2

Views: 6837

Answers (4)

none
none

Reputation: 12087

(these work for me in vim)

using block select:

14l<C-v>jj6ly7lp

using macro (if lengths are varied):

record the macro using:

qqf(;vf)y;pj0q

and then repeat as neccessary:

100@q

works for a file with 100 lines

Upvotes: 1

Raj
Raj

Reputation: 3462

I combine the techniques given by bmearns and Kev.

So what I did is as follows

  1. start recording the macro by q.
  2. /( to find the opening bracket, so it goes to the second one.
  3. n to goto the third one.
  4. v to mark the visual block
  5. /) to search for the end of the bracket
  6. y to copy the visual block
  7. n to goto next ) bracket
  8. One time arrow key to go next to the closing bracket
  9. p to paste the visual block
  10. Down Arrow key to goto next line.
  11. Home Key to goto first location of the next line.
  12. q to stop recording the macro
  13. @a to do the same operation for all the lines.

And it worked just completely fine ! Thanks a lot guys !

Upvotes: 0

Jay
Jay

Reputation: 57899

If all the lines are the same length and format as in your example:

With cursor anywhere on or inside of parens (A B C):

va(Ctrl+v

Now you have (A B C) selected and are in block select mode. Use any mechanism to block select downward. If it is a few lines, you can just move downward. If it is many you can add a count, or use a search (/) or end of file Shift+g.

Once you have selected all:

y/)Enterp

This will yank (y) the whole block, move to the close paren, and paste the block after it (p).

If the lines vary in length or otherwise cannot be reasonably selected as a block

You can use a pattern replacement. This is specific to your example, where we are looking for the pattern (A B C) where A, B and C are capital letters contained in parentheses and separated by spaces. We take a match of that pattern plus the following space, and replace it with the match of that pattern, a space, and the pattern match again.

:%s/\(([A-Z] [A-Z] [A-Z])\) /\1 \1/

Upvotes: 3

brianmearns
brianmearns

Reputation: 9967

Yes, several ways to do this in vim (as with most things). I would probably opt for a quick macro: go to the first line and hit qa from normal mode to start recording a macro named "a". Now do the edit on that line manually. Of course you'll want the operations to be generic, so don't just type in the values, use yank and put to copy it. Once the edit is done, escape to normal mode and press j to move down to the next line (this will set you up to run the macro on the next line). Hit q again to stop recording, then type @a to execute the macro on the next line, then hit it again to run it on the next line, etc. Or, once you do @a once, you can do @@ to run the same macro again. You can also supply a count to @@ to do is several times.

Alternatively, you can do a regex with the :s command, but it depends on what your lines actually look like and how good you are with regex.

Upvotes: 1

Related Questions