初识Linux(六)------ vim 程序编辑器

Linux 在命令行下的文本编辑器有非常多,常常听到的就有: emacs, pico, nano, joe, 与 vim 等等。 既然有这么多命令行的文本编辑器,那么我们为什么一定要学 vi ?这是因为:
  • 所有的 Unix Like 系统都会内置 vi 文本编辑器,其他的文本编辑器则不一定会存在;
  • 很多个别软件的编辑接口都会主动调用 vi (例如未来会谈到的 crontab, visudo, edquota 等指令);
  • vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计;
  • 程序简单,编辑速度相当快速。

  其实重点是上述的第二点,因为有太多 Linux 上面的指令都默认使用 vi 作为数据编辑的接口,所以必须、一定要学会 vi ,否则很多指令你根本就无法操作。

1. vi 的使用

  基本上 vi 共分为三种模式,分别是“一般命令模式”、“编辑模式”与“命令行模式”。 这三种模式的作用分别是:

  • 一般命令模式 (command mode)

     以 vi 打开一个文件就直接进入一般指令模式了(这是默认的模式,也简称为一般模式)。在这个模式中, 你可以使用“上下左右”按键来移动光标,你可以使用“删除字符”或“删除整列”来处理文件内容, 也可以使用“复制、粘贴”来处理你的文件数据。

  • 编辑模式 (insert mode)

     在一般指令模式中可以进行删除、复制、粘贴等等的动作,但是却无法编辑文件内容的,要等到你按下“ i, I, o, O, a, A, r, R ”等任何一个字母之后才会进入编辑模式。注意,通常在 Linux 中,按下这些按键时,在画面的左下方会出现“ INSERT 或 REPLACE ”的字样,此时才可以进行编辑。而如果要回到一般指令模式时, 则必须要按下“Esc”这个按键即可退出编辑模式。

  • 命令行模式 (command-line mode)

     在一般模式当中,输入“ :  /  ? ”三个中的任何一个按钮,就可以将光标移动到最下面那一列。在这个模式当中, 可以提供你“查找数据”的动作,而读取、保存、替换字符、离开 vi 、显示行号等等的动作则是在此模式中完成。

  一般命令模式可与编辑模式及命令行界面切换, 但编辑模式与命令行界面之间不可互相切换。

执行范例

1. 使用“ vi filename ”进入一般指令模式

[dmtsai@study ~]$ /bin/vi welcome.txt
# 在 CentOS 7 当中,由于一般帐号默认 vi 已经被 vim 取代了,因此得要输入绝对路径来执行才行!

 

  直接输入“ vi 文件名”就能够进入 vi 的一般指令模式了。不过请注意,由于一般帐号默认已经使用 vim 来取代,因此如上表所示, 如果使用一般帐号来测试,得要使用绝对路径的方式来执行 /bin/vi。另外,请注意,记得 vi 后面一定要加文件名,不管该文件名存在与否。

2. 按下 i 进入编辑模式,开始编辑文字

3. 按下 [ESC] 按钮回到一般指令模式

4. 进入命令行界面,文件储存并离开 vi 环境

   :wq  write(保存)和 quit(退出),如果没有写入的权限,可以  :wq! 来强制写入。

1.1 按键说明

  • 一般命令模式可用的按键说明,光标移动、复制粘贴、搜索替换等

 

  •  一般命令模式切换到编辑模式的可用按键说明

 

  •  一般命令模式切换到命令行界面的可用按键说明

 

   在 vi 中,“数字”是很有意义的,数字通常代表重复做几次的意思,也有可能是代表去到第几个什么什么的意思。

1.2 vim 的缓存、恢复与打开时的警告信息

  当我们在使用 vim 编辑时, vim 会在与被编辑的文件的目录下,再创建一个名为 .filename.swp 的文件。如果你的系统因为某些原因掉线了, 导致你编辑的文件还没有保存,这个时候  *.swp 就能够发挥恢复的功能了。

范例,vim man_db.conf 后,按下 ctrl+z后 vim 会到后台执行,在 kill vim 进程,模拟系统故障。再 vim vim man_db.conf 可以看到

[dmtsai@study vitest]$ vim man_db.conf

E325: ATTENTION  <==错误代码
Found a swap file by the name ".man_db.conf.swp"  <==下面数列说明有缓存的存在
          owned by: dmtsai   dated: Mon Jul  6 23:54:16 2015
         file name: /tmp/vitest/man_db.conf  <==这个缓存属于哪个实际的文件?
          modified: no
         user name: dmtsai   host name: study.centos.vbird
        process ID: 31851
While opening file "man_db.conf"
             dated: Mon Jul  6 23:47:21 2015

下面说明可能发生这个错误的两个主要原因与解决方案!
(1) Another program may be editing the same file.  If this is the case,
    be careful not to end up with two different instances of the same
    file when making changes.  Quit, or continue with caution.
(2) An edit session for this file crashed.
    If this is the case, use ":recover" or "vim -r man_db.conf"
    to recover the changes (see ":help recovery").
    If you did this already, delete the swap file ".man_db.conf.swp"
    to avoid this message.

Swap file ".man_db.conf.swp" already exists! 下面说明你可进行的动作
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:  

 

  由于缓存存在的关系,因此 vim 会主动的判断你的这个文件可能有些问题,在上面的图示中 vim 提示两点主要的问题与解决方案,分别是这样的:

问题一:可能有其他人或程序同时在编辑这个文件:

  由于 Linux 是多用户多任务的环境,因此很可能有很多人同时在编辑同一个文件。如果在多人共同编辑的情况下, 万一大家同时保存,那么这个文件的内容将会变的乱七八糟!为了避免这个问题,因此 vim 会出现这个警告窗口! 解决的方法则是:找到另外那个程序或人员,请他将该 vim 的工作结束,然后你再继续处理。

  如果你只是要看该文件的内容并不会有任何修改编辑的行为,那么可以选择打开成为只读(O)文件, 亦即上述输入英文“ o ”即可,其实就是 [O]pen Read-Only 的选项。

问题二:在前一个 vim 的环境中,可能因为某些不知名原因导致 vim 中断 (crashed):

  这就是常见的不正常结束 vim 产生的后果。解决方案依据不同的情况而不同,常见的处理方法为:

  如果你之前的 vim 处理动作尚未保存,此时你应该要按下“R”,亦即使用 (R)ecover 的项目, 此时 vim 会载入 .man_db.conf.swp 的内容,让你自己来决定要不要保存。这样就能够救回来你之前未保存的工作。 不过那个 .man_db.conf.swp 并不会在你结束 vim 后自动删除,所以你离开 vim 后还得要自行删除 .man_db.conf.swp 才能避免每次打开这个文件都会出现这样的警告。

  如果你确定这个缓存是没有用的,那么你可以直接按下“D”删除掉这个暂存盘,亦即 (D)elete it 这个项目即可。 此时 vim 会载入 man_db.conf ,并且将旧的 .man_db.conf.swp 删除后,创建这次会使用的新的 .man_db.conf.swp。

 

  至于这个缓存警告信息的界面中,有出现六个可选按键,说明如下:

  •   [O]pen Read-Only:打开此文件成为只读文件, 可以用在你只是想要查阅该文件内容并不想要进行编辑行为时。
  • (E)dit anyway:还是用正常的方式打开你要编辑的那个文件, 并不会载入缓存的内容。不过很容易出现两个使用者互相改变对方的文件等问题。
  • (R)ecover:就是载入缓存内容,用来恢复之前未储存的工作。 不过当你救回来并且储存离开 vim 后,还是要手动删除那个缓存文件。
  • (D)elete it:你确定那个缓存是无用的,那么打开文件前会先将这个缓存删除。
  • (Q)uit:按下 q 就离开 vim ,不会进行任何动作回到命令提示字符。
  • (A)bort:忽略这个编辑行为,感觉上与 quit 非常类似! 

2. vim 的额外功能

  其实,目前大部分的 distributions 都以 vim 取代 vi 的功能了,如果你使用 vi 后,却看到界面的右下角有显示目前光标所在的行列号码,那么你的 vi 已经被 vim 所取代。为什么要用 vim 呢?因为 vim 具有颜色显示的功能,并且还支持许多的程序语法 (syntax), 因此,当你使用 vim 编辑程序时 (不论是 C 语言,还是 shell script ), vim 可帮你直接进行debug。

[dmtsai@study ~]$ alias
....其他省略....
alias vi='vim

  这表示当你使用 vi 这个指令时,其实就是执行 vim 。如果你没有这一列,那么你就必须要使用 vim filename 来启动 vim 。基本上, vim 的一般用法与 vi 完全一模一样。

 

 2.1 可视区块(Visual Block)

  刚刚我们提到的简单的 vi 操作过程中,几乎提到的都是以行为单位的操作。那么如果我想要搞定的是一个区块范围呢(也就是以列为操作单位)? 举例来说,像下面这种格式的文件:

192.168.1.1    host1.class.net
192.168.1.2    host2.class.net
192.168.1.3    host3.class.net
192.168.1.4    host4.class.net
.....中间省略......

  假设我想要将 host1, host2... 等等复制0, 并且加到每一行的后面,亦即每一行的结果要是“ 192.168.1.2 host2.class.net host2 ”这样的情况时, 在传统或现代的窗口型编辑器似乎不容易达到这个需求,但是 vim 是办的到的。那就使用可视区块(Visual Block),当我们按下 v 或者 V 或者 [Ctrl]+v 时, 这个时候光标移动过的地方就会开始反白,这三个按键的意义分别是:

 

 

1. 使用 vim hosts 来打开该文件
2. 将光标移动到第一列的 host 那个 h 上头,然后按下 [ctrl]-v ,左下角出现区块示意字样:

3. 将光标移动到最底部,此时光标移动过的区域会反白!如下图所示:


4. 此时你可以按下“ y ”来进行复制,当你按下 y 之后,反白的区块就会消失不见。
5. 最后,将光标移动到第一列的最右边,并且再用编辑模式向右按两个空白键,回到一般指令模式后, 再按下“ p ”后,如下图所示:

 

 2.2 多文件编辑

  假设一个例子,你想要将刚刚我们的 hosts 内的 IP 复制到你的 /etc/hosts 这个文件去, 那么该如何编辑?我们知道在 vi 内可以使用 :r filename 来读入某个文件的内容, 不过,这样毕竟是将整个文件读入啊!如果我只是想要部分内容呢?这个时候多文件同时编辑就很有用了。 我们可以使用 vim 后面同时接好几个文件来同时打开,相关的按键有:

1. 通过“ vim hosts /etc/hosts ”指令来使用一个 vim 打开两个文件;
2. 在 vim 中先使用“ :files ”查看一下编辑的文件数据?结果如下所示。 至于下图的最后一列显示的是“按下任意键”就会回到 vim 的一般指令模式中!

 

 

 2.3 多窗口功能

  想像两种情况:

  • 当我有一个文件非常的大,我查阅到后面的数据时,想要“对照”前面的数据, 是否需要使用 [ctrl]+f 与 [ctrl]+b (或 pageup, pagedown 功能键) 来跑前跑后查阅?
  • 我有两个需要对照着看的文件,不想使用前一小节提到的多文件编辑功能;

  在命令行界面输入“:sp {filename}”即可!那个 filename 可有可无, 如果想要在新窗口启动另一个文件,就加入文件名,否则仅输入 :sp 时, 出现的则是同一个文件。

 

 2.4 vim 的关键字补全功能

  我们知道 bash 的环境下面可以按下 [tab] 按钮来达成指令/参数/文件名的补全功能,在vim里有

 

   比较有用的是第1, 3 这两个组合键,第一个组合按键中,你可能会在同一个文件里面重复出现许多相同的关键字, 那么就能够通过这个补全的功能来处理。如果你是想要使用 vim 内置的语法检验功能来处理取得关键字的补全,那么第三个项目就很有用了。 不过要注意,如果你想要使用第三个功能,就得要注意你编辑的文件的扩展名。

2.5 vim 环境设置与记录: ~/.vimrc, ~/.viminfo

  有没有发现,如果我们以 vim 软件来搜索一个文件内部的某个字串时,这个字串会被反白, 而下次我们再次以 vim 编辑这个文件时,该搜寻的字串反白情况还是存在呢!甚至于在编辑其他文件时, 如果其他文件内也存在这个字串,哇!竟然还是主动反白耶!真神奇! 另外,当我们重复编辑同一个文件时,当第二次进入该文件时, 光标竟然就在上次离开的那一列上头呢!真是好方便啊~但是,怎么会这样呢?

  这是因为我们的 vim 会主动的将你曾经做过的行为记录下来,好让你下次可以很轻松。那个记录行为动作的文件就是: ~/.viminfo !如果你曾经使用过 vim, 那你的主文件夹应该会存在这个文件。这个文件是自动产生的, 你不必自行创建。而你在 vim 里头所做过的动作,就可以在这个文件内部查询到~ ^_^

  vim 的环境设置参数有很多,如果你想要知道目前的设置值,可以在一般指令模式时输入“ :set all ” 来查阅,不过.....设置项目实在太多了~所以,在这里仅列出一些平时比较常用的一些简单的设置值, 提供参考

 

  但是是否每次使用 vim 都要重新设置一次各个参数值? 这不太合理吧?所以,我们可以通过配置文件来直接规定我们习惯的 vim 操作环境。整体 vim 的设置值一般是放置在 /etc/vimrc 这个文件,不过,不建议修改他! 你可以修改 ~/.vimrc 这个文件 (默认不存在,需手动创建),将你所希望的设置值写入! 举例来说,可以是这样的一个文件:

[dmtsai@study ~]$ vim ~/.vimrc
"这个文件的双引号 (") 是注解
set hlsearch            "高亮度反白
set backspace=2         "可随时用倒退键删除
set autoindent          "自动缩排
set ruler               "可显示最后一列的状态
set showmode            "左下角那一列的状态
set nu                  "可以在每一列的最前面显示行号啦!
set bg=dark             "显示不同的底色色调
syntax on               "进行语法检验,颜色显示。

  在这个文件中,使用“ set hlsearch ”或“ :set hlsearch ”,亦即最前面有没有冒号“ : ”效果都是一样的,至于双引号则是注释符号。

3. vim 使用注意事项

3.1 中文编码的问题

  有时候vim可能无法正常显示中文,这可能是编码的问题。中文编码有Big5、GBK与UTF-8等几种,由于编码的不同,可能就会乱码。你得要考虑许这些:

  • Linux 系统默认支持的语系数据:这与 /etc/locale.conf 有关;
  • 终端接口 (bash) 的语系: 这与 LANG, LC_ALL 这几个变量有关;
  • 文件原本的编码;
  • 打开终端机的软件,例如在 GNOME 下面的窗口界面。

  事实上最重要的是后两点,只要这两点的编码一致,就能够正确显示中文。

  在 Linux 本机前的 tty1~tty6 原本默认就不支持中文编码,现在假设文件编码为GBK,而且环境是使用 Linux 的 GNOME ,启动的终端接口为 GNOME-terminal 软件, 通常是这样来修正语系编码:

[dmtsai@study ~]$ LANG=zh_CN.gb18030
[dmtsai@study ~]$ export LC_ALL=zh_CN.gb18030

  然后在终端工具栏的“终端”-->“设置字符编码” -->“中文 (简体)”项目点选一下。

3.2 DOS 与 Linux 的换行符

  Windows的DOS与Linux的换行符不同,利用 cat -A观察DOS建立的文件的特殊格式,分析在DOS使用的换行符为 ^M$ ,我们称为 CR 与 LF 两个字符, 而在Linux下只要 LF($)这个换行符。这个换行符对于 Linux 的影响很大,为什么呢?

  在 Linux 下命令在开始执行时,判断依据是 “Enter”,而 Linux 的 Enter 为 LF 符号, 不过,由于 DOS 的换行符是 CRLF ,也就是多了一个 ^M 的符号出来, 在这样的情况下,如果是一个 shell script 的程序文件,将可能造成程序无法执行,因为他会误判程序所下达的指令内容。

  那只能进行转换了,需要安装 dos2unix-*

[dmtsai@study ~]$ dos2unix [-kn] file [newfile]
[dmtsai@study ~]$ unix2dos [-kn] file [newfile]
选项与参数:
-k  :保留该文件原本的 mtime 时间格式 (不更新文件上次内容经过修订的时间)
-n  :保留原本的旧文件,将转换后的内容输出到新文件,如: dos2unix -n old new

  在不同的系统之间复制一些纯文本时,千万记得要使用 unix2dos 或 dos2unix 来转换一下换行符。

ps:目前还没遇到这种情况,可能是没使用过脚本文件。

3.3 语系编码转换

[dmtsai@study ~]$ iconv --list
[dmtsai@study ~]$ iconv -f 原本编码 -t 新编码 filename [-o newfile]
选项与参数:
--list :列出 iconv 支持的语系数据
-f     :from ,接原本的编码;
-t     :to ,新编码;
-o file:如果要保留原本的文件,那么使用 -o 新文件名,可以创建新编码文件。

范例一:将 /tmp/vitest/vi.big5 转成 utf8 编码吧!
[dmtsai@study ~]$ cd /tmp/vitest
[dmtsai@study vitest]$ iconv -f big5 -t utf8 vi.big5 -o vi.utf8
[dmtsai@study vitest]$ file vi*
vi.big5: ISO-8859 text, with CRLF line terminators
vi.utf8: UTF-8 Unicode text, with CRLF line terminators

 

posted @ 2022-10-28 17:24  莫莫君不恋爱  阅读(452)  评论(0编辑  收藏  举报