How to swap odd and even lines in vi?

Viewed 237

Say I have this kind of code:

__device__ ​ float __cosf (float x);
//Calculate the fast approximate cosine of the input argument.
__device__ ​ float __exp10f (float x);
//Calculate the fast approximate base 10 exponential of the input argument.
__device__ ​ float __expf (float x);
//Calculate the fast approximate base e exponential of the input argument.
__device__ ​ float __fadd_rd (float x, float y);
//Add two floating point values in round-down mode.
__device__ ​ float __fadd_rn (float x, float y);
//Add two floating point values in round-to-nearest-even mode.
__device__ ​ float __fadd_ru (float x, float y);
//Add two floating point values in round-up mode.

How I can swap odd and even lines in vi ?

4 Answers

you could define a key which wil swap 2 lines: :map <F2> ddp<Down>

It seems that there are not much line, so hitting 'F2' a couple of times will swap the lines...

My output

//Calculate the fast approximate cosine of the input argument.
__device__  float __cosf (float x);

//Calculate the fast approximate base 10 exponential of the input argument.
__device__  float __exp10f (float x);

//Calculate the fast approximate base e exponential of the input argument.
__device__  float __expf (float x);

//Add two floating point values in round-down mode.
__device__  float __fadd_rd (float x, float y);

//Add two floating point values in round-to-nearest-even mode.
__device__  float __fadd_rn (float x, float y);

//Add two floating point values in round-up mode.
__device__  float __fadd_ru (float x, float y);

I made it with one command in vi:

:%s/\(__device.*\n\)\(.*$\)/\2^M\1/g

There is a one trick though. To enter ^M I pressed Ctrl-V and then pressed Enter key.

Explanation in detail:

Basically to replace all matches of something in vi command is:

%s/something/other/g

Instead of slash any symbol can be used. So

%s,something,other,g 

does the same.

"something" is what we look for and "other" is replacement.

In my case I was looking for word "__device" followed by any symbols ( .* stands for "anything") and then ending by newline \n.

I marked parts of search string I want to reuse with \( \).

Dollar stands for "end of line".

And then I just put it all back in opposite order with \2 and \1.

to enter newline I pressed Ctrl-V and then Enter.

I hope this explains. Note, I use vim which stands for Vi Improved. Old school simple VI may lack some features. In most unixes these days installing package "vim" will make it available when not there by default.

EDIT: Actually you can omit dollar sign. .* anyway searches till end of line only. But I think I keep it in answer because sometime regexp needs it and this is useful knowledge.

Here's a quick'n'dirty trick. In normal mode, type:

qaddpjq

… then:

1000@a

First row is recording a macro : qa starts recording in macro "a", dd deletes current line and stores it in default buffer, p places it back after current row (formerly the next one), j skips to next row, then q again stops macro recordings.

Afterwards, @a calls the macro and 1000 repeats it a thousand times, since we can't use a movement-based action nor a visual selection here.

It works on my machine but you should care about the number of rows to swap, as the state of your last two rows after processing.

With VScode one can achieve the same with a regex replace with:

(__device.*\n)(.*$)

and

$2\n$1
Related