如何在vi中交换奇数行和偶数行?

How to swap odd and even lines in vi?

假设我有这样的代码:

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

如何在 vi 中交换奇数行和偶数行?

我的输出

//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);

我用 vi 中的一个命令完成了它:

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

虽然有一个技巧。要输入 ^M,我按了 Ctrl-V,然后按了回车键。

详细说明:

基本上替换 vi 命令中的所有匹配项是:

%s/something/other/g

可以使用任何符号代替斜线。所以

%s,something,other,g 

也一样。

"something" 是我们寻找的,"other" 是替换的。

在我的例子中,我正在寻找单词“__device”,后跟任何符号(.* 代表 "anything"),然后以换行符结尾 \n

我用 \( \) 标记了要重复使用的部分搜索字符串。

美元代表"end of line"。

然后我将它们以 </code> 和 <code> 的相反顺序全部放回去。

为了输入换行符,我按了 Ctrl-V,然后按了 Enter。

我希望这能解释清楚。请注意,我使用 vim 代表 Vi Improved。老派的简单 VI 可能缺少一些功能。现在在大多数 unix 中,安装包 "vim" 将在默认情况下不存在时使其可用。

编辑:实际上你可以省略美元符号。 .* 无论如何只搜索到行尾。但我想我会保留它作为答案,因为有时正则表达式需要它,这是有用的知识。

您可以定义一个将交换 2 行的键: :map <F2> ddp<Down>

好像行数不多,所以按'F2'几次会换行...

这是一个快速又肮脏的技巧。在正常模式下,输入:

qaddpjq

……然后:

1000@a

第一行正在录制宏:qa 开始录制宏 "a",dd 删除当前行并将其存储在默认缓冲区中,p 将其放回在当前行(以前是下一行)之后,j 跳到下一行,然后 q 再次停止宏录制。

之后,@a调用宏并1000重复一千次,因为我们不能在这里使用基于移动的动作或视觉选择。

它在我的机器上工作,但你应该关心要交换的行数,作为处理后最后两行的状态。

使用 VScode 可以用 正则表达式替换 实现相同的效果:

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

\n