vim 的宏与寄存器
目标
亲自确认宏的本质——它只是保存在寄存器中的文本——并掌握设计可重复执行宏的方法。
为什么重要
用 qa 录制的宏,本质上是把按键输入作为原始字符串保存在寄存器 a 中。yank 与宏之所以共用 a~z 这片空间,原因就在这里。理解这一点后,就能把宏导出到文件中编辑,再重新载入;也可以像本实验一样把宏作为文件提交并验证。可重复执行的宏还有一套设计原则:**绝对固定起点、根据内容移动、最后前往下一个目标。**缺少其中任何一项,从第二行开始就会错位。
步骤
在 /root/vmac 目录中工作。宏文件中应将按键输入写成一行。
- 在
/root/vmac/list.txt中写入以下 6 行。web01/web02/db01/db02/cache01/queue01 - 将把每行变成
- web01这种形式的宏按键保存到/root/vmac/macro1.txt,应用结果保存到/root/vmac/bulleted.txt。 - 将把每行变成
"web01",的宏保存到/root/vmac/macro2.txt,结果保存到/root/vmac/quoted.txt。该宏中必须包含 ESC 字符。 - 将在每行前添加
1.、2.等行号的 ex 命令保存到/root/vmac/number.ex,结果保存到/root/vmac/numbered.txt。 - 在
/root/vmac/hosts.txt中写入以下 6 行。web01.prod.example.com/web02.staging.example.com/db01.prod.example.com/db02.staging.example.com/cache01.prod.example.com/queue01.staging.example.com然后,将只在包含 staging 的行开头添加#的命令保存到/root/vmac/onlystaging.ex,结果保存到/root/vmac/staging.txt。 - 将从
hosts.txt中收集包含prod的行并追加到文件末尾(总计 9 行)的命令保存到/root/vmac/collect.ex,结果保存到/root/vmac/collected.txt。 - 在
/root/vmac/table.txt中写入以下 5 行。name=web01/role=frontend/zone=seoul/port=8080/tier=gold将把每行变成NAME:web01这种形式,即键转为大写、等号改为冒号的宏保存到/root/vmac/macro3.txt,结果保存到/root/vmac/table_out.txt。 - 将在
hosts.txt中只保留 prod 行,并在前面添加-、后面添加:80的命令保存到/root/vmac/final.ex,结果保存到/root/vmac/final.txt。
提示
- 评分器会把宏文件的第一行放入寄存器,再用
:%normal @q应用到所有行。 - 通过
:normal执行的插入模式会在命令结束时自动退出,因此如果宏最后一步是插入,就不需要 ESC。只有中途需要结束插入模式时才需要它。 - 使用
:reg a可以直接查看寄存器内容。 - 常见错误 1:第 2 步宏末尾的空格在保存时被去掉,会得到
-web01。 - 常见错误 2:第 6 步使用小写寄存器会每次覆盖,最后只剩一行。
创建练习列表
在 /root/vmac/list.txt 中写入以下 6 行。
web01 / web02 / db01 / db02 / cache01 / queue01
必须正好 6 行,顺序也要一致。
第一个宏:添加项目符号
将把每行变成 - web01 这种形式的宏按键保存到 /root/vmac/macro1.txt,应用结果保存到 /root/vmac/bulleted.txt。
I 从行首开始输入。宏末尾的一个空格也必须原样保存在文件中。
在宏中加入 ESC 字符
将把每行变成 "web01", 的宏保存到 /root/vmac/macro2.txt,结果保存到 /root/vmac/quoted.txt。该宏中必须包含 ESC 字符。
退出插入模式的按键也是宏的一部分。在 Vim 中先按 Ctrl-V,再按 Esc,就能把该字符写入文件。
添加行号
将在每行前添加 1. 、2. 等行号的 ex 命令保存到 /root/vmac/number.ex,结果保存到 /root/vmac/numbered.txt。
每行的值不同,因此不能使用固定字符串。替换语法中有一种形式可以在替换位置求值表达式(expression)。
只应用到符合条件的行
在 /root/vmac/hosts.txt 中写入以下 6 行。
web01.prod.example.com / web02.staging.example.com / db01.prod.example.com / db02.staging.example.com / cache01.prod.example.com / queue01.staging.example.com
然后,将只在包含 staging 的行开头添加 # 的命令保存到 /root/vmac/onlystaging.ex,结果保存到 /root/vmac/staging.txt。
使用 :g/模式/normal 按键输入 这种形式,把行过滤器与 Normal 模式按键组合起来。
把分散的行收集到一处
将从 hosts.txt 中收集包含 prod 的行并追加到文件末尾(总计 9 行)的命令保存到 /root/vmac/collect.ex,结果保存到 /root/vmac/collected.txt。
小写寄存器会覆盖内容,大写寄存器则会追加。收集完成后,粘贴到文件末尾。
组合两个操作的宏
在 /root/vmac/table.txt 中写入以下 5 行。
name=web01 / role=frontend / zone=seoul / port=8080 / tier=gold
将把每行变成 NAME:web01 这种形式,即键转为大写、等号改为冒号的宏保存到 /root/vmac/macro3.txt,结果保存到 /root/vmac/table_out.txt。
先用文本对象把一个单词改为大写,再接上字符查找与单字符替换。
综合过滤、前缀和后缀
将在 hosts.txt 中只保留 prod 行,并在前面添加 - 、后面添加 :80 的命令保存到 /root/vmac/final.ex,结果保存到 /root/vmac/final.txt。
按顺序组合前面使用过的技巧。先筛选要保留的行,在顺序上更有利。