Xupeng's blog

圆外之大,心向往之

VIM 魔术: 图文实例展示

绩效评估,计算工作时间,顺便就拿 VIM 来说事吧,在 VIM 中变个小魔术,完成这个小任务;) 原始材料是这样的:

original text

这是原始的按照时间顺序进行的统计。我想要的结果是,分别计算出每人的工作时间,那么第一步,去掉每行末尾的 “Indicator Edit Delete”。 首先录制一个宏,可以在命令模式下使用这样的按键序列:ggqd0fId$jq 把这串按键序列分开来开是这样的意思:

  • gg: 回到文件的第一行
  • q: 开始录制一个宏
  • d: 定义了宏的名字是 d
  • 0: 回到行首
  • fI: 光标在行内移动到第一个 I 字符处
  • d$: 删除从光标处到行尾的所有字符
  • j: 移动到下一行
  • q: 结束宏的录制

okay,宏录制完了,把它绑定到 F7 键上,这样子: :map <F7> @d<Enter> 这是一个冒号命令,就是在命令模式下,依次输入上面的按键(<Enter>指代回车),好,现在可以一直按着 F7 键不动,很快文件就变成了下面的样子:

original text

ok, 接下来我得让同一个人的记录放在一起,也就是得按照人名对文件进行排序,那首先要做的就是把人名从行的中间换到行首,还是得定义一个宏,来方便使用,命令模式下按键序列是这样的:ggqs0v11lx$pjq 理解了上一个宏的定义,这个就很简单了,意思就是,回到文件的第一行,定义一个名为 s 的宏,这个宏所进行的操作是:从行首开始,选择 11 个字符,然后把这 11 个字符删除,再回到行尾,把这 11 个字符粘贴出来,然后光标移动到下一行。 宏定义完了,依然是把这个宏绑定到一个特殊功能键上,这次使用<F6>: :map <F6> @s<Enter> 绑定键之后,一直按 F6 键,很快文件就变成了下面的样子:

original text

嗯,排序的准备工作已经做好了,接下来使用一个外部命令 sort 来对文件进行排序: :%!sort<Enter> okay, 文件现在已经有点型了,哈哈。

original text

那再接下来怎么办呢?嗯,准备生成一段简单的 Python 代码来完成计算。先把第一个人的工作时间给取出来,这次用到了块选择模式,先回到第一行,怎么回?在命令模式下 gg 呗,之前已经用过啦;) 然后移动光标到时间记录上,可以使用 f2,这是一个行内搜索/移动,f向前查找 2,并将光标移动到 2 上,然后块选择模式,在命令模式下 CTRL-v,然后移动光标选上第一个人的所有时间记录,就是下面这个图的样子:

original text

选中以后 y 键复制所选内容到 VIM 的 buffer 中,okay,现在回到文件末尾,要处理这些时间啦。继续上按键序列:G2o<ESC><ESC>

  • G:快速移动光标到文件末行
  • 2o:在当前行下产生两个空行
  • <ESC><ESC> : 按两次ESC键,回到命令模式

okay,p 键粘贴刚才复制过的时间记录,文件就成了下面的样子:

original text

接下来我要把这些抽取出来的时间记录变成 Python 的算术表达式;) 看,我首先在 41 行到 42 行做一个往行尾追加一个+号的动作:

:41,42s/$/ +/g<Enter>

这实际上是一个替换操作,是指把 41 行到 42 行之间每行的行尾这个位置,替换成 “+”,因为 $ 只是一个位置,并不是一个字符,所以实际的效果,就是在每行的行尾追加了 +”。

好,完成一大半啦,马上就要变成 Python 的算术表达式啦:

接下来用可视模式选中 41 到 43 行,可以这样:41GvG,意思就是先跳转到 41 行,进入可视模式,再回到文件末尾,效果呢就是选中了 41 到 43 行,选中以后按 J,嗯,选中的行就连接成了一行,就是下面的效果:

original text

哈,依葫芦画瓢吧,用同样的方法把其他人的时间记录也整理成上面的样子,之后呢,做一下小小的编辑,就成了下图的简单 Python 代码:

original text

快要完成啦,现在需要删掉原始的那些统计文本,只留下可爱的 Python 代码,使用按键序列:40Gdgg, 如果你有耐心看到这里,想必一定明白这是在做什么吧,对啦,就是先移动到 40 行,然后做删除动作,从当前行一直删除到文件首,喏,就变成了下图的样子啦:

original text

ho,总算完成了,执行这段再简单不过的 Python 代码,得出计算结果:

:!python %<Enter>

original text

做这个时间统计和计算时,习惯性的使用 VIM,用到了很多平时经常用到并且的确很有用的 VIM 操作,就做了一下记录,以分享给需要的人;)

Comments