Search code examples
vi

How to swap odd and even lines in vi?


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 ?


Solution

  • 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.