Linux开发环境及应用·第三周·vi编辑器

本文整理了vi编辑其使用方法和常见的问题

vi用于编辑文件,它有一个增强版命令叫vim,语法上vim是兼容vi的,只需要学习好vi就基本可以使用vim了,下面是整理到的笔记

用户配置文件

用户的HOME目录下,存在一个.exrc文件(每个用户独立配置),在里面可以配置vi编辑器的一些偏好设置,比如是否显示行号,制表符的长度等等。

最常用的配置为:

  • set number # 显示行号
  • set tabstop=4 # 制表符长度为4

这里不详细记录其它配置

工作状态

vi有两种工作状态,分别为命令状态(启动时进入此状态)和文本状态

在命令状态下,键盘输入解释成命令,按键无回显;输入冒号:后,可以输入行编辑命令(与不输入冒号:的命令是不一样的),按键有回显,按下回车键后才执行;i和a命令可以进入文本状态

在文本状态下,键盘输入解释为输入的文本,按键有回显,按下Esc键可以回到命令状态

课程中的一幅形象的图:
vi工作状态

命令

编辑

可以使用以下两个编辑命令来进入文本状态:

  • i i是insert的缩写,意思是插入,在光标位置之前插入字符
  • a a是append的缩写,意思是附加,在光标位置之后追加字符

光标移动

命令状态下,使用以下命令来移动光标:

  • h
  • j
  • k
  • l

经查阅,这种怪异的移动光标的方式是历史造成的,原因是旧时的键盘大多没有方向键。不过,现在vi编辑器一般可以使用方向键来移动光标

命令前加一个整数,表示这个命令连续执行多少遍,如:

  • 5h 左移5列
  • 6j 下移6行

翻页

翻页使用的命令为:

  • Ctrl-b (按下Ctrl键和b键,不是输入Ctrl-b) 向后翻页 (字母b是backward的缩写,后退)
  • Ctrl-f 向前翻页 (字母f是forward的缩写,前进)

一般可以使用PgDn键(Page Down)代替Ctrl-f,用PgUp键(Page Up)代替Ctrl-b

也可以在命令前加上整数表示执行的次数,如:6Ctrl-f表示向前翻6页

光标行内快速移动

在行内快速移动光标的命令主要有以下几个:

  • ^ 移动光标至行首
  • $ 移动光标至行尾
  • w 右移一个单词
  • b 作移一个单词

命令前加上整数的方式同样适用

移动光标到指定行

  • :123 将光标定位至123行
  • :$ 将光标定位至文件尾,即最后一行
  • 描述行号时,$表示最后一行,圆点.表示当前行
  • 将光标移动到一个括号上,按下%键可将光标定位至该括号匹配的括号上

其它常用命令

这里列出其它常用的命令:

  • 删除命令:
    • x 删除当前光标处的一个字符,5x表示删除从当前光标开始的5个字符
    • dd 删除当前行,3dd表示删除从当前行开始的3行
  • r 替换字符,ra表示将当前光标处的字符替换成a
  • 撤销与重复:
    • u 撤销上一次编辑操作
    • 圆点键. 重复上一次编辑操作
  • 存盘:
    • ZZ 存盘退出
    • :wq 存盘退出
    • :w 存盘
    • :q! 不存盘退出
  • 读取文件:
    • :r file 读入文件file的内容插入到当前行之后
  • 写入文件:
    • :50,$w file 把第50行到文件尾的内容写到file中
    • :50,$w! file 同上,且强制覆盖
  • 剪贴板相关:
    • 剪切:
      • :10,50d 剪切第10~50行
      • :1,.d 剪切文件首至当前行
      • :.,$d 剪切整个文件
    • 拷贝:
      • :10,50y 拷贝10~50行
    • p 粘贴
  • 块操作:
    • :5,10co56复制第5~10行到第56行下
    • :8,34m78 移动第8~34行到第78行下
  • J 将下面的一行合并到当前行
  • Ctrl-l 刷行屏幕显示,字母l是load的缩写,译为“加载”
  • Ctrl-g 状态显示,在屏幕最下面一行列出正在编辑的文件的名字,总行数,当前行号,文件是否被修改过等信息

模式查找

这里将模式查找相关的操作独立写出来。

vi使用正则表达式来描述一个字符串模式

查找命令格式为:/pattern,如/[0-9][0-9]*表示查找数字;按下n可以向下继续查找,N则表示向上查找,当查找遇到文件尾则回到文件头继续搜索

替换命令

还可以使用模式查找来替换字符串,格式为::n1,n2s/pattern/string/flags

其中flags是选项,经查阅,flags有以下四个选项:

  • c (confirm的缩写) 每次替换前询问
  • e (error的缩写) 不显示错误
  • g (globle的缩写) 全部替换;不加g选项,只替换每行的第一个匹配到的字符串
  • i (ignore的缩写) 忽略大小写

注意:选项可以合并使用

例:

  • :1,50s/abc/xyz/ 将1~50行中出现的字符串abc替换成xyz
  • :50,80s/^/ / 将第50~80行右移4列(缩进)
  • :1,$s/ *$// 消除行尾多余空格

转义符用\,分隔符不一定要使用/,可以使用:^等,举例如下:
将buf.len/1000替换成buffer.size/1024可用以下的命令:

  • :1,$s/buf\.len\/1000/buffer.size\/1024/g
  • 1,$s:buf\.len/1000:buffer.size/1024:g
  • 1,$s^buf\.len/1000^buffer.size/1024^g

\(\)

在模式描述中增加\(\)不影响匹配操作,但是替换字符串的时候可以使用\1\2\3等表示第一对\(\)之间匹配到的内容,第二对,第三对……,\0表示匹配到的整个字符串

例如,替换C语言源程序文件中格式如“变量名->number”的字符串替换成“变量名->num”的格式,使用如下命令:
:1,$s/\([a-zA-Z][a-zA-Z0-9]*\)->number/\1->num/g

疑难杂症

“死机”问题

记录下刚开始使用vi/vim,因为不熟悉,可能导致“死机”的解决方式。

“死机”症状:vi编辑完后执行存盘操作,结果屏幕卡死,输入任何信息都没有响应

原因:vi编辑结束后按下Ctrl-S(大部分Windows编辑器的保存按键),Linux进入流量控制状态

解决方法:按下Ctrl-Q键解除流量控制

RS232接口连接主机和终端时的流量控制方案

源自历史原因,以前会出现终端显示速度跟不上主机发送的速度的现象,因为主机送来的数据打印出来的速度较慢,或者需要将屏幕显示的内容暂停显示来仔细分析,所以此时需要一种机制来控制主机发来的数据流量

有两种控制方法:

  • 硬件方式:使用RS232接口的CTS信号线(Clear To Send),但缺点是:需要在电缆中增加一条通信线
  • 软件方式:利用流控字符Xon和Xoff,这是ASCII码表中的控制字符,ASCII码值分别为17和19

而Ctrl-S按键发送Xon字符,Ctrl-Q按键发送Xoff字符

但是到了如今,网络虚拟终端在主机和终端之间使用TCP协议,TCP协议本身有流量控制的功能,终端显示速度落后于数据生成速度可以由TCP解决,而且如今因网速太快和缓冲等,很难将信息暂停到感兴趣的位置,故手动Xon/Xoff控制流量已经没什么用处了,但为了与历史机制的兼容仍保留了此机制。


“意外中止”问题

症状:vi编辑结束后存盘,程序“意外中止”,且编辑成果丢失

原因:vi存盘命令ZZ按键为Shift-zz,误操作为Ctrl-zz,而Ctrl-z按键导致当前运行进程被挂起,进程暂停运行

解决方法:
恢复进程运行即可,jobs命令可以查看当前bash后台的进程(作业)列表,使用如下命令可以恢复:

+ fg %1 将1号作业恢复到前台运行
+ %1 将1号作业恢复到前台运行

退格键无法使用的问题

症状:bash命令输入时,Backspace键可用,但是,运行自己写的程序时Backspace键无法正常使用

原因:当前终端的“行律”设置不正确

解决方法:
Backspace按键对应的ASCII码是控制字符Ctrl-H,执行stty erase ^H,设定行律模块把Ctrl-H为删除符,以后Ctrl-H和Backspace都可以做删除。如果需要,把命令放到$HOME/.bash_profile
stty -a可以了解终端行律的状态


乱码问题

屏幕显示乱码

症状:cat /bin/bashhead -n 1 /bin/bash导致屏幕乱码,键盘输入也只能看到画表用的制表符

原因:/bin/bash文件不是文本文件,这些二进制内容逐字节送到终端,凑巧一个序列被终端理解为一个转义序列,执行动作,修改了终端字符集

解决方法:

  • 断开连接,重复登录
  • 注意不要把非文本信息在终端输出

文本文件格式问题

症状:Linux下的文本文件在Windows用notepad(记事本)打开,所有内容粘在一行

原因:Linux和Windows的文本文件的存储格式不同

解决方法:在Linux完成格式转换后再用Windows处理,或者用Windows中可容忍Linux文本文件格式的其它编辑器

文本文件的存储格式:

  • Linux:行尾处仅存换行符 \n
  • Windows:行尾处存回车和换行符 \r\n

相关命令:dos2unix/unix2dos,todos/frodos、file(查看文件数据类型)

中文编码问题

症状:从Windows迁来的文件,只有在显示中文字符时是乱码。Linux本生的中文信息正常显示

原因:中文字符集GBK和UTF8不兼容,Windows使用GBK,而Linux使用UTF8

GBK编码:Windows默认中文编码方案,两个字节表示一个汉字,字节的最高位为1,以区别ASCII码(最高位为0)

UTF8编码:众多Linux默认中文编码方案,三个字节表示一个汉字,字节的最高位为1

转换编码方式(使用iconv命令):

  • iconv -f gbk -t utf8 file1 -o file2 从gbk转换到utf8
  • iconv -f utf8 -t gbk file1 -o file2 从utf8转换到gbk

终端乱码

症状:终端中文显示乱码

原因:还是字符集的问题

解决方法:调整终端仿真软件的终端类型和字符编码,具体方式与所用的软件有关