目录
vim/neovim 如何在文本文件中操作数字
增加或减少数值的命令
增加的命令
-
[count]CTRL-A
:(助记:add)对光标下或光标后面的数字加[count]
,默认加 1。例如,现有文本如下:
I have 5 apples.
移动光标到数字 5 上,在正常模式下,按下快捷键:
CTRL-A
,数字加1
。I have 6 apples.
按下数字
0
,光标到行首,然后,4CTRL-A
,4 + 6 = 10,光标跳到最后的数字0
上。I have 10 apples.
-
[count]{Visual}CTRL-A
:对选中的数字加[count]
,默认加 1。 -
[count]{Visual}g CTRL-A
:对选中的数字加[count]
。如果选中多行,则每行的数字都会递增[count]
,因此可以有效地生成[count]
个递增的序列。例如,在文档的空白处,行首位置插入一定数量的数字
0.
,可以在 normal (常规)模式下,敲入命令:4o0. <Esc>
。0. 0. 0. 0.
移动光标到第一个数字
0
上,CTRL-V
进入可视块模式,向下移动光标选择所有的数字0
,也可以选择这些行,
然后g CTRL-A
,结果如下:1. 2. 3. 4.
再一个示例:先输入以下内容,可以通过输入一行后复制而得:
yy9p
。或者键入:10omyArray[0] = 0;<ESC>
。myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0; myArray[0] = 0;
然后,移动光标到第一个中括号中的
0
位置,CTRL-V
进入可视块模式选择所有中括号中的数字0
,然后g CTRL-A
,结果如下:myArray[1] = 0; myArray[2] = 0; myArray[3] = 0; myArray[4] = 0; myArray[5] = 0; myArray[6] = 0; myArray[7] = 0; myArray[8] = 0; myArray[9] = 0; myArray[10] = 0;
减少的命令
[count]CTRL-X
:对光标下或后面的数字减[count]
,默认减 1。[count]{Visual}CTRL-X
:对可视选择的文本中的数字减[count]
。[count]{Visual}g CTRL-X
:对选择的文本中的数字减[count]
,如果选择了多行,则对其中的数字递减[count]
,因此,可以有效地生成[count]
递减的序列。
备注:CTRL-A
和 CTRL-X
命令对有符号的整数,无符号的二进制、八进制、十六进制,及字母字母有效。这是基于 'nrformats'
的如何设置。具体请查询帮助 :h 'nrformats'
。
在宏中使用的示例
CTRL-A
命令在宏中非常有用。示例:使用以下步骤创建一个带数字的列表。
1. 创建第一个列表项,确保以数字开始。
2. qa - 开始宏录制,并把以下操作记录到寄存器 'a' 中
3. yy - 复制整行
4. p - 在当前行下粘贴复制的内容
5. CTRL-A - 数字加 1
6. q - 停止宏录制
7. <count>@a - 重复这个复制、粘贴和加 1 动作 '<count>' 次
与 .
u
两个命令结合使用小技巧
在使用 ctrl-A
和 CTRL-X
中,可以充分利用 .
和 u
两个命令,其中 .
命令可以重复上一次的修改,而 u
命令可以撤销上一次操作。这样在很多场景中比较好用,大幅减少组合键按压,另外,也要利用好只要光标在要修改的数字前面就可以操作的特点。即先在一个位置操作 ctrl-A
,然后就可以使用 .
命令重复该动作,如果不小心点击多了,则点击 u
进行撤销即可,然后移动光标到适当位置,继续使用 .
命令 … 。
使用函数或语句实现
put 和 range 函数配合使用
想要得到如下的序列:
10
11
12
13
14
15
只需把光标移动到需要插入数字的上一行,然后在命令行输入::put =range(10, 15)
回车即可。如果想要在文件开头插入数字序列: :0put =range(1, 2)
,此时无需关心光标的位置。类似的,如果想要在文件末尾插入序列::$put =range(5, 7)
。
如果想在当前行后插入带格式的序列,可以使用以下命令:
:put =map(range(11,15), 'printf(''%04d'', v:val)')
就会产生以下序列:
0011
0012
0013
0014
0015
想要插入横向的数字序列:
20 21 22 23 24 25 26 27 28 29 30
可以在命令行输入以下命令:
:put =join(range(20, 30))
结合 redir、#、p # 和 d、put
EX 命令的 #
等同于 number
, 能够打印的基础上,在行首加入行号;redir 命令可以重定向到文件、寄存器或变量等。d 表示删除, put 会粘贴到指定位置。
:redir @q | 34, 38# | redir END
:34, 38d | put q
命令解释:第一个命令,把带有行号的第 34 行至 38 行内容重定向到寄存器 q
中。第二条命令是,先删除这几行,然后粘贴寄存器的内容,从而实现了添加行号的目的。
可以参见帮助::h :#
、:h redir
等。
结合 let、g 和 s 命令实现序列输入
想要实现以上 10~15 序列,可以这样操作,先输入 6 个 1 :
1
1
1
1
1
1
在命令行输入以下命令:
:let i=10 | g/1/s//\=i/ | let i=i+l
如果想插入奇数或者偶数,只要调整let i=n
和 let i=i+?
即可,i 初始值 n 可以从需要的值开始,? 可以为 1 或 2。
结合 for 循环语句
想要得到以下 IP 地址列表:
192.168.9.115
192.168.9.116
192.168.9.117
192.168.9.118
192.168.9.119
192.168.9.120
只需光标移动到需要插入 IP 地址的上一行,然后在命令行执行:
:for i in range(115, 120) | put = '192.168.9.'. i | endfor
注意,如果模板中需要单引号,由于双引号会导致结束,可以使用转义后的双引号,或者使用两个单引号转义成一个单引号加以解决:
:for i in range(1001, 1003) | put = \"hello '\" . i |endfor
或者
:for i in range(1001, 1003) | put = 'hello ''' . i |endfor
hello '1001
hello '1002
hello '1003
结合 read 与 seq 外部命令
:read !seq m n
例如: :read !seq 10 15
以上命令可以生成序列,注意这个组合只能在 linux 中使用。
10
11
12
13
14
15
结合 s
替换命令和 printf
函数实现
如果文档中已有内容,想在每行的行首插入行号。
例如,现有文档如下:
这是第一行
这是第二行
这是第四行
可以在命令行进行如下操作:
:%s/^/\=printf('%4d ', line('.'))/
001 这是第一行
002 这是第二行
003
004 这是第四行
以上命令解释如下:
% - 代表全文范围,也可以先选择某些连续行,执行以上不带 % 的命令,可以实现局部插入行号
s - 替换命令缩写
^ - 查找行首位置
printf - 格式化打印函数,'%4d' 表示右对齐,占4个位置;'%-4d'表示左对齐;'%04d'表示前置 0 等
line('.') - 取得当前行行号
如果想要在非空行插入行号,可以使用以下命令:
:g/./ s/^/\=printf('%4d ', line('.'))/
001 这是第一行
002 这是第二行
004 这是第四行
使用外部命令 nl
该命令作用是:对文件的行进行编号。
在 shell 中 man nl
可查其帮助。
-w:设置数字的宽度
-n: 设置对齐方式,ln, rn等
-v: 设置其实数值
...
原始文本:
这是第一行
这是第二行
这是第四行
执行以下命令行命令作用:数字宽度 2,右对齐,起始值 5
:1, 4!nl -w2 -n rn -v5
其结果是:
5 这是第一行
6 这是第二行
7 这是第四行
将十进制数字转换为 16 进制数字或二进制、八进制等
例如我们有一些十进制数字:
3 30
8 15
10
20
100
可以使用以下命令行命令实现转换成 16 进制:
:%s/\v\d+/\=printf("%X", submatch(0))/g
# \v 表示 very magic,可以减少反斜杠转义的使用数量,参见帮助:':h /\v' 。
# submatch(0) 用于替换命令中的表达式中,表示匹配的内容。
得到结果是:
3 1E
8 F
A
14
64
统计文本中匹配模式的数量
如果需要统计所有的字符数量:
:%s/.//gn
如果需要统计所有的单词数量(英文):
:%s/\v\w+//gn
如果要统计完全匹配的 hello 单词数量:
:%s/\v<hello>//gn
备注:替换命令的标志:n
只会报告匹配到的数量,不会实际进行替换。