分类: LINUX
2011-09-07 20:28:31
第一章 vim常用开发技巧
启动VI时的选项
vi +n file 打开文件到n行
vi + file 打开文件到最后一行
vi +/pattern file 打开文件到模式首次出现的位置
启动vim以后,可以通过:e 打开文件
模式切换
好了,现在我们总结一下模式间切换的方法
其它模式==>普通模式
Esc
普通模式==>插入模式
i 在光标前插入 I 在行首插入
a 在光标后插入 A 在行末插入
o 在当前行之下新建行 O 在当前行之上新建行
r 替换当前字符 R 从当前字符开始替换
普通模式==>命令模式
:
普通模式==>可视模式
v 可视模式
V 可视块模式
移动
在普通模式中,您可以使用以下方式移动光标
j 向下
k 向上 k
l 向右 h l
h 向左 j
您可以使用其它更有效率的方式移动光标
w 下一个单词词首 W 将特殊符号视为单词的一部分
b 上一个单词词首 B 同上
e 单词末尾 E 同上(忽略标点)
0 行首 ^ 行首文字(行首空格之后)
$ 行末
( 移动到当前句子的开始
) 移动到下一句子的开始
{ 移动到当前段落的开始
} 移动到下一段落的开始
〔〔 移动到当前节的开始
〕〕 移动到下一节的开始
注解:为了找到句子的尾部,VI将寻找标点符号?、。!中的一个,当这些标点后至少有2个空格,或者作为一行的最后一个非空格字符出现,
VI就认为找到了句尾的位置。
H 页面顶部
M 页面中部
L 页面底部
在其它模式中,您可以使用方向键移动光标,不过我们不推荐您那样作,您可以在配置文件中绑定插入模式下的功能键
noremap!
noremap!
noremap!
noremap!
………………
<作用范围> <键位> <功能>
其中,map!绑定的键盘映射,作用于所有模式;inoremap!绑定的映射,仅作用于插入模式。
数字参数
您也可以使用数字参数,来重复执行。例如
100j 执行100次j键,向下100行
或者作为跳转的行号、百分比。见下面的 浏览 部分
<行号> Ctrl+g 按行号跳转
标记
您可以在当前光标处作一个标记,以便快速返回
m<标记名称> 定义标记。标记名称为一个字符
'(单引号)<标记名称> 移到光标到<标记名称>行的首字符。
`(反引号) <标记名称> 移动光标到<标记名称>所标记的字符。
`` 返回到移动前的上一标记或上下文的确切位置
'' 返回到上一标记或上下文所在行的开始。
浏览
gg 文件首行
G 文件末行
<行号>G 按行号转到相应行
<1~100>% 按百分比转到相应的行数
zz 将光标所在行调整至页面中间
Tip
gg 定位到文件首行, V 进入可视行模式, G 定位到文件末行,实现类似“全选”的功能。依次按下 g g V(Shift+v) G(Shift+g)
编辑
x 剪切当前字符
dd 剪切当前行
y 复制可视模式选取字符
yy 复制当前行
p 在光标后粘贴 P 在光标前粘贴
u 撤消
r字符 所有字符替换为新字符
u U ~ 分别是所有字母变小写、变大写、反转大小写
> < 分别是缩进和反缩进
~ 将当前光标处内容进行大小写转换
注:vim把最近的9次删除操作保存在9个已编号的删除缓冲区内,可用 "+数字+p 命令将之粘贴出来。例如"3p就会把3号缓冲区的
内容粘贴出来。
调换两个的顺序:xp
使用J合并两行,将光标置于第一行的任意一个位置上,命令模式,J可以把当前行和下面一行合并起来。
寄存器操作
Vim可以将不同字段剪切或复制到不同寄存器中,您可以从不同寄存器中取出内容后粘贴
"<寄存器名称> 按下“"”键和另一个字符键,便可以定义一个寄存器。例如:
"a "1
定义寄存器后直接进行操作
"ayy 将当前行复制到寄存器 a 中
"ap 将寄存器 a 中的内容粘贴到光标之后
通常情况下,寄存器 + ( " + Shift+= )对应X下的剪贴板。您在其它程序中复制的内容,可以使用 "+p 粘贴到Vim中;
您在Vim中,可以使用 "+y 将内容复制到剪贴板,再粘贴到其它程序中
没有指定寄存器时,Vim使用“无名寄存器”存储内容
使用撤销分支功能
可以使用 :undolist 命令查看缓冲区存在的撤销分支列表。而通过 :undo <> 命令则能够移到撤销的某个分支。
搜索和替换
按下 / 键,编辑器底部会出现 / 符号,接着输入字符串,便可以进行搜索
/ 向下搜索 ? 向上搜索
n 搜索下一个
N 搜索上一个
注:
可以在搜索某个模式之后,做些编辑工作,然后还可以通过n和N,/和?对同一模式进行再次搜索。
可以把/和?与c和d之类的文本修改命令结合在一起使用。如:d?move
:s/<源字符串>/<目标字符串> 将源字符串替换为目标字符串
:s/<源字符串>/<目标字符串>/g 替换当前行中所有符合条件的字符串
:<行号1>,<行号2>s/<源字符串>/<目标字符串>/g 在指定行中进行替换
:%s/<源字符串>/<目标字符串>/g 全文替换
正则表达式
在搜索和替换时,可以使用正则表达式进行匹配
^ 行首 $ 行尾
. 匹配除换行符之外的任何一个单字字符,空格也视为字符。
^ 匹配 以...作为一行的开头
$ 匹配以.....作来一行的末尾
〔 〕 匹配括号内所包含的字符中的任何一个
\< 在单词的开始
\> 或结尾 匹配字符
~ 匹配上次搜索中使用的任何正规表达式。
更多的替换技巧:
:s回车与:&与:s//~/相同,即重复上次替换。
宏
您可以将一系列的操作录制为一个宏,然后执行它
q<宏名称> 开始录制宏。宏名称为一个字符
q 录制中按下“q”键,结束录制
@<宏名称> 执行宏
插入模式下的快捷键
键绑定、缩写
前面我们已经向您介绍了键绑定,
map!
尖括号及其中的内容,为Vim配置文件的约定,分别描述了按键和功能,表示将功能编写到按键上。如果绑定的只是普通字符,例如:
map! xxx XXXXX
表示将 fXXXXX 绑定到 xxx 上。当您键入 xxx 时,编辑器会自动替换为 XXXXX 。
如果您只是想将字符串绑定为缩写,方便输入,我们建议您使用 iabbrev 来绑定。例如:
iabbrev ubt Ubuntu
在插入模式下键入 ubt ,编辑器会自动替换为 Ubuntu 。您可以将 iabbrev 命令缩写为 iab ,例如:
iab ubt Ubuntu
以上命令,您可以直接在命令模式下输入,临时启用。也可以写入配置文件,永久启用。
单词补全
您可以在配置文件中定义补全的方式
"自动补全方式:(使用逗号分隔)
set complete=k,.
" . 当前文件
" b 已被装缓冲区,但是没有在窗口内的文件
" d 在当前的文件中定义和由#include包含进来的文件
" i 由#include包含进来的文件
" k 由dictionary选项定义的文件
" kfile 名为{file}的文件
" t 标记(tags)文件
" u 没有载入的缓冲区
" w 在其他窗口中的文件
"设定自动补全字典 :
set dictionary=path
4.5 插入补全
在插入模式下,为了减少重复的击键输入,VIM 提供了若干快捷键,当你要输入某个上下文曾经输入过的字符串时,你只要输入开头若干字符,使用快捷键,VIM 将搜索上下文,找到匹配字符串,把剩下的字符补全,你就不必敲了。
这样,编程序时你起多长的变量名都没关系了,:-) 而且还可以减少输入错误。我认为,插入补全是 VIM 最为突出的一项功能。
i
i
i
i
如果按
命令模式
前面介绍了普通模式和插入模式。我们发现,普通模式主要用来浏览和修改文本内容,而插入模式则用来向文本中添加内容。
而命令模式则多用于操作文本文件(而不是操作文本文件的内容),例如保存文件;或者用来更改编辑器本身的状态,例如设定多栏窗口、标签或者退出编辑器……
w(rote) 将更改写入文件
:w
:e! 放弃本次会话所做的任何修改,返回到文件的初始状态。
q(uit) 退出编辑器:
:q
某些情况下,编辑器会阻止命令的执行。例如您修改了文件,而没有保存,那么您使用 :q 命令退出时,编辑器就不会执行这条命令,而是提醒您保存文件。
这个时候,您可以在命令末尾追加 ! 来强制执行命令
:<命令>!
例如 :q! ,即便您没有保存已修改的文件,使用此命令,编辑器也会放弃修改而强行退出
多栏窗口
您可以使用以下命令,将当前窗口水平分为两栏
:new
新建一栏空白窗口
:split
将当前文件分两栏显示
同理,您可以使用下列命令,将当前窗口垂直分为两栏
:vnew
:vsplit
先按下
如果您希望当前命令在所有栏中生效,您可以在命令的末尾追加 all
:<命令>all
例如:
:qall
如果您希望这条命令强制执行,那么 ! 位于命令的最末
:<命令>all!
例如:
:qall! 强行退出所有栏窗口
:set scrollbind 设置卷动绑定属性。所有设置了卷动绑定属性的窗口将一起卷动。
可以用 :set noscrollbind 解除绑定
标签页
Vim在7以后的版本,开始支持标签页的功能
:tabe /path/to/file.txt-在一个新的 tab 页中打开文件
:tabnew-新建一个 tab 页
:tabs-查看 tab 页列表,通过“>”显示当前窗口、“+”显示可修改的缓冲区
:tabc-关闭当前的 tab 页
:tab split-在当前缓冲区使用新的 tab 页打开文件
:tabn-切换到下一个 tab 页
:tabp-切换到上一个 tab 页
:tabr[ewind]-转到第一个 tab 页
:tabf[irst]-与上一命令作用相同
多数情况下,您可以使用鼠标点击标签进行切换
4. VIM 的其它命令
要真正使用 VIM,光靠 vi 的基本命令当然不行,下面就来介绍更多的命令。以下的命令,有些是 VIM 特有的,有些在 vi 中也存在,我就不加区分了。
其中,以“:”开头表示该命令在命令行输入,以“i”开头表示这是插入模式下的命令,其它则是普通模式下的命令。
4.1 使用帮助
有关正则表达式的使用
UNIX/LINUX下的很多工具之所以强大、灵活,关键是因为有了正则文法和元字符,这也是VIM乃至
UNIX/LINUX系统的精华所在。正因为使用灵活,因此掌握起来比较吃力,如果不是真正理解,实际运用中会
出现千奇百怪的错误。因此,有必要对这部分知识多花些气力。下面结合具体实例讲解。
例五、有一文件,包含某外企的中国员工的资料,首先是姓名,然后是两个空格,其次是15位身份证号码。
zhang.fei 430759701022003
diao.chan 651302801225012
guan.yu 342869680413001
xi.shi 120638780214006
liu.bei 210324650708001
现在,有以下问题需要解决:
按照外国人的习惯,应该是名在前,姓在后。因此,文件中的姓名字段需要修改。
姓与名的首字母应该大写。
根据身份证号码,还可以判断出生年月日,将其作为一个新字段添加。
根据身份证号码,可以判断出性别。若为男性,添加male,若为女性,添加female 。
将男女员工分开,男员工在前,女员工在后。
将各字段数据左对齐
最终结果如下:
Fei.Zhang 430759701022003 1970/10/22 male
Yu.Guan 342869680413001 1968/04/13 male
Bei.Liu 210324650708001 1965/07/08 male
-----------------------------------------------
Chan.Diao 651302801225012 1980/12/25 female
Shi.Xi 120638780214006 1978/02/14 female
为了完成上述功能,只需执行脚本employee.vim ,使用方法为 :so employee.vim 回车即可。
脚本内容如下:
:%s/ / /
:%s/\(............\)\( *\)/\1/
:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/
:%s/$/ xxxxxx/
:%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/
:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3
:%s/$/ xxxxxx/
:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /
:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/
:$
:s/.*/&^M-----------------------------------------------
:g/female/.m$
在这个脚本中,使用了大量的正则表达式,这里仅对涉及到的正则表达式做一简要介绍。有关正则表达式的
内容相当多,本文不可能占用大量篇幅叙述,请大家谅解。
% 地址范围符号,代表文件中的所有行,作用等同于地址范围 1,$
. 与任意单字符(换行符除外)匹配,例如 y.s 可以匹配 yas y.s 或 y s 等等。
* 与前一字符的0次或多次出现匹配,例如 y*s 可以匹配 yys yyyyys 或 s 等等。
$ 与行尾匹配。
& 代表模式匹配中出现的字符串,例如 s/abc/&def 是把当前行的abc替换成abcdef 。
[] 匹配[]中出现的字符,例如[abc]匹配字符 a,b 或 c ,[a-zA-Z]匹配所有的英文字符。
\( \) \(和\)之间出现的内容可以由\num来替代。
\1\2\3 替代\(和\)之间出现的内容。
\u 将后续字符串的首字母大写。
\{num\} 与前一字符的num次出现匹配。
现在,我们对脚本逐条讲解,希望能帮助大家理解正则文法。
⑴:%s/ / /
将文件中每行出现的2个空格替换为10个空格。
zhang.fei 430759701022003
diao.chan 651302801225012
guan.yu 342869680413001
xi.shi 120638780214006
liu.bei 210324650708001
⑵:%s/\(............\)\( *\)/\1/
保留行首的12个字符,将其余的空格删除,这样,前两个字段就对齐了。
zhang.fei 430759701022003
diao.chan 651302801225012
guan.yu 342869680413001
xi.shi 120638780214006
liu.bei 210324650708001
⑶:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/
将文件中每行出现的雇员姓名互换,并将首字母大写。
Fei.Zhang 430759701022003
Chan.Diao 651302801225012
Yu.Guan 342869680413001
Shi.Xi 120638780214006
Bei.Liu 210324650708001
⑷:%s/$/ xxxxxx/
在每一行的行尾添加2个空格和6个x
Fei.Zhang 430759701022003 xxxxxx
Chan.Diao 651302801225012 xxxxxx
Yu.Guan 342869680413001 xxxxxx
Shi.Xi 120638780214006 xxxxxx
Bei.Liu 210324650708001 xxxxxx
⑸:%s/\([0-9]\{6\}\)\([0-9]\{6\}\)\([0-9]\{3\}\) \(xxxxxx\)/\1\2\3 \2/
将xxxxxx替换成出生年月日。
Fei.Zhang 430759701022003 701022
Chan.Diao 651302801225012 801225
Yu.Guan 342869680413001 680413
Shi.Xi 120638780214006 780214
Bei.Liu 210324650708001 650708
⑹:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3
将年月日用/字符分隔,并在年前添加19。
Fei.Zhang 430759701022003 1970/10/22
Chan.Diao 651302801225012 1980/12/25
Yu.Guan 342869680413001 1968/04/13
Shi.Xi 120638780214006 1978/02/14
Bei.Liu 210324650708001 1965/07/08
⑺:%s/$/ xxxxxx/
在每一行的行尾添加2个空格和6个x
Fei.Zhang 430759701022003 1970/10/22 xxxxxx
Chan.Diao 651302801225012 1980/12/25 xxxxxx
Yu.Guan 342869680413001 1968/04/13 xxxxxx
Shi.Xi 120638780214006 1978/02/14 xxxxxx
Bei.Liu 210324650708001 1965/07/08 xxxxxx
⑻:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /
身份证号码末位是奇数的,将xxxxxx替换成male
Fei.Zhang 430759701022003 1970/10/22 male
Chan.Diao 651302801225012 1980/12/25 xxxxxx
Yu.Guan 342869680413001 1968/04/13 male
Shi.Xi 120638780214006 1978/02/14 xxxxxx
Bei.Liu 210324650708001 1965/07/08 male
⑼:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/
身份证号码末位是偶数的,将xxxxxx替换成female
Fei.Zhang 430759701022003 1970/10/22 male
Chan.Diao 651302801225012 1980/12/25 female
Yu.Guan 342869680413001 1968/04/13 male
Shi.Xi 120638780214006 1978/02/14 female
Bei.Liu 210324650708001 1965/07/08 male
⑽:$ 到文件的最后一行
⑾:s/.*/&^M-----------------------------------------------
在文件的最末行插入一行 "-" 字符。
Fei.Zhang 430759701022003 1970/10/22 male
Chan.Diao 651302801225012 1980/12/25 female
Yu.Guan 342869680413001 1968/04/13 male
Shi.Xi 120638780214006 1978/02/14 female
Bei.Liu 210324650708001 1965/07/08 male
-----------------------------------------------
⑿:g/female/.m$
将所有的女员工记录移至文件尾。
Fei.Zhang 430759701022003 1970/10/22 male
Yu.Guan 342869680413001 1968/04/13 male
Bei.Liu 210324650708001 1965/07/08 male
-----------------------------------------------
Chan.Diao 651302801225012 1980/12/25 female
Shi.Xi 120638780214006 1978/02/14 female
笔者目前正在为某外资公司从事大型机(IBM S/390)的软件开发,一切工作都在TSO环境中进行。为了对编
写的程序进行测试,必须准备测试数据。有过大型机开发经验的人会知道,通过TSO,输入字符型数据还可
以,如果要输入16进制数据,操作起来很麻烦。因为16进制数是纵向排列的,输入时既不方便,又很容易错
位。怎么解决呢?我尝试了几种办法,实际证明,用VIM最方便。
例六、下列数据 1234567890ABCDEF ,将其变成 13579ACE 24680BDF 的形式,这样,数据就可以很方便的
粘贴到TSO环境中了。
下面给出宏命令脚本change_d.vim
"----------------------------------------------------
"Macro Function : Convert Char Arrange Direction
"
" Sample : 40 50 60 ==> 4 5 6
" 0 0 0
" Date : 2001/12/01
" Author : Yan Shi
"----------------------------------------------------
:s/.*/&^M/
:1
:map = malx+$p-`al=
说明如下:
⑴ :s/.*/&^M/ 在数据行下方添加一空行。
⑵ :1 回到文件的首行的首字符。
⑶ :map = malx+$p-`al= 将一大串VIM命令映像给字符'='
① ma 将首字符标记为a
② l 光标右移一个字符
③ x 删除光标处字符
④ + 移至下一行
⑤ $ 到行尾
⑥ p 将删除的字符粘贴
⑦ - 回至上一行
⑧ `a 返回到标记字符处
⑨ l 光标右移一个字符
⑩ = 递归调用,重复以上步骤,直到将该行所有的数据处理完。
1.交换两个字符位置
xp
2.上下两行调换
ddp
3.把文件内容反转
:g/^/m0/ (未通过)
4.上下两行合并
J
5.删除所有行
dG
6.从当前位置删除到行尾
d$
7.从当前位置复制到行尾
y$ 如果要粘贴到其他地方 p 就可以了
由于vi 是建立在 EX 上的, 所以当键入":"时就来到了EX命令状态
8. :ab string strings
例如 ":ab usa United States of America" ,
当你在文见里插入 usa 时
United States of America 就蹦出来了
9. :map keys new_seq
定义你当前 键盘命令
10. :set [all]
vi or ex 的编辑状态
如 显示每行 :set nu
11.在命令状态下,nyy表示拷贝从光标行起的下n行内容,p表示paste,可刚复制的内容粘贴在光标处的
下面。
12.单个字符替换用r,覆盖多个字符用R,用多个字符替换一个字符用s,整行替换用S
13. :%s/old_word/new_word/g
这个指令是于在整个文件中替换特定字符串
14.光标控制
k:上移 nk 上移n行
j:下移 nj 下移n行
即将第n到m的行存到a寄存器,以此类推,b,c........寄存器等
这样就可以将你常用的需要复用的内容粘贴到不同的寄存器中以备用
将光标移到第n行,按下 ma
将光标移到第m行,按下 "ay'a
想粘贴到某处,直接将光标移到某地,按下 'ap 即可,以此类推,b,c........寄存器等
在当前屏幕中
H 跳到第一行
M 跳到中间一行
L 跳到最后一行
15. .重复上一次修改!
表8-2 删除命令
删除命令操作
d l 删除当前字符(与x命令功能相同)
d 0 删除到某一行的开始位置
d ^ 删除到某一行的第一个字符位置(不包括空格或TAB字符)
d w 删除到某个单词的结尾位置
d 3 w 删除到第三个单词的结尾位置
d b 删除到某个单词的开始位置
d W 删除到某个以空格作为分隔符的单词的结尾位置
d B 删除到某个以空格作为分隔符的单词的开始位置
d 7 B 删除到前面7个以空格作为分隔符的单词的开始位置
d) 删除到某个语句的结尾位置
d 4) 删除到第四个语句的结尾位置
d( 删除到某个语句的开始位置
d } 删除到某个段落的结尾位置
d { 删除到某个段落的开始位置
d 7 { 删除到当前段落起始位置之前的第7个段落位置
d d 删除当前行
d /t e x t 删除从文本中出现" t e x t"中所指定字样的位置,一直向前直到下一个该字样所出现的
位置(但不包括该字样)之间的内容
d fc 删除从文本中出现字符"c"的位置,一直向前直到下一个该字符所出现的位置(包括
该字符)之间的内容
d tc 删除当前行直到下一个字符" c"所出现位置之间的内容
D 删除到某一行的结尾
d $ 删除到某一行的结尾
5 d d 删除从当前行所开始的5行内容
d L 删除直到屏幕上最后一行的内容
d H 删除直到屏幕上第一行的内容
d G 删除直到工作缓存区结尾的内容
d 1 G 删除直到工作缓存区开始的内容
修改命令操作
c l 更改当前字符
c w 修改到某个单词的结尾位置
c 3 w 修改到第三个单词的结尾位置
c b 修改到某个单词的开始位置
c W 修改到某个以空格作为分隔符的单词的结尾位置
c B 修改到某个以空格作为分隔符的单词的开始位置
c 7 B 修改到前面7个以空格作为分隔符的单词的开始位置
c 0 修改到某行的结尾位置
c) 修改到某个语句的结尾位置
c 4) 修改到第四个语句的结尾位置
c( 修改到某个语句的开始位置
c } 修改到某个段落的结尾位置
c { 修改到某个段落的开始位置
c 7 { 修改到当前段落起始位置之前的第7个段落位置
c tc 修改当前行直到下一个字符c所出现位置之间的内容
C 修改到某一行的结尾
c c 修改当前行
5 c c 修改从当前行所开始的5行内容
表8-4 替换命令
替换命令操作
s 将当前字符替换为一个或多个字符
S 将当前行替换为一个或多个字符
5 s 将从当前字符开始的5个字符替换为一个或多个字符
vi替换使用规则:
:g/s1/s/s2/s3/g
第一个g表示对每一个包括s1的行都进行替换,
第二个g表示对每一个包括s1的行所有的s2都用s3替换
s表示替换
s1是被替换字符串
s2是要被替换的字符串,他可以和s1相同(如果相同的话用//代替)
s3是替换字符串
16.往右移动到 x 字符上 fx
往左移动到 x 字符上 Fx
往右移动到 x 字符前 tx
往左移动到 x 字符后 Tx
(注意:以上四个命令中,其中x是键入的字符)
;分号,配合 f 和 t 使用,重复一次
,逗号,配合 f 和 t 使用,反方向重复一次
17. vi 环境选项 Solaris ksh
noautoindent nomodelines noshowmode
autoprint nonumber noslowopen
noautowrite nonovice tabstop=8
nobeautify nooptimize taglength=0
directory=/var/tmp paragraphs=IPLPPPQPP LIpplpipnpbtags=tags /usr/lib/tags
noedcompatible prompt tagstack
noerrorbells noreadonly term=vt100
noexrc redraw noterse
flash remap timeout
hardtabs=8 report=5 ttytype=vt100
noignorecase scroll=11 warn
nolisp sections=NHSHH HUuhsh+c window=23
nolist shell=/bin/ksh wrapscan
magic shiftwidth=8 wrapmargin=0
mesg noshowmatch nowriteany
For C-Shell:
setenv EXINIT "set nu"
For Bourne or Korn Shell:
EXINIT="set nu"; export EXINIT
For Korn Shell Only (alternate method):
typeset -x EXINIT="set nu"
在 .profile 里设置 vi 的环境选项 , 以上均测试过
18. 标记文本
mchar 用字母char标记当前光标的位置
`char 移至char所标记处
'char 移至char标记所在行的开头处
" 移至当前行上一次所在位置(在光标移动之后)――一个双引号
'' 移至当前行上第一次所在位置的行的开头处(在光标移动之后)――两个单引号
19. 同时vi多个文件时,CTRL-SHIFT-6回到上一个文件,在本次vi的文件和上次vi的文件之间切换。
但是我发现一个BUG:在用CTRL-SHIFT-6切换到上一个文件后,用:args查看多文件vi状态时,屏幕底部仍然
显示目前vi的是刚才的文件。(在HP-UX,Solaris,AIX上通过)
也可以使用:
:e#
进行切换
20. sco 下VI 要在文本前同样的字符加用
%s/^/要加的内容/g 要在文本后同样的字符加
%s/$/要加的内容/g
21.
如何去掉文本中的^M 硬回车?不必用binary传回去再ascii传回来的方式,用shell或者unix语句实现。
cat filename |tr -d '\015' >newfile
不同的unix系统还存在一些其他不同的命令,如:doscp
sed 也可以实现这个功能.
dos2unix filename filename2
反之
unix2dos filename filename2
在vi 中用:$s/^M//g
^是crtl-V crtl-M
22.如何在"unix命令行"下将一个文件的某字符串用另一个串换掉
sed 's/string1/string2/gp' file1 > file2
23.将/etc/hosts下所有的地址都ping 2次
1 #/usr/bin/sh
2 #grad /etc/hosts and ping each address
3 cat /etc/hosts|grep -v '^#' | while read LINE
4 do
5 ADDR=`awk '{print $1}'`
6 for MACHINE in $ADDR
7 do
8 ping $MACHINE -n 2
9 done
10 done
24.到前一个函数[[ ,
到下一个函数]] ,
括号配对% ,
交叉参考Ctrl_] (事先用ctags做索引),
回来用e# ` 编辑一个函数:vi -t 函数名 ,编辑加密文本vi -X
25.在插入模式下ctrl+p,自动补齐剩余单词,依赖规则:tags,以有的单词等等
在普通模式中,命令以按键形式输入。而在命令行中,命令以字符串形式输入
: 进入命令行
i 或 a 进入插入模式。区别是:i 进入插入模式后,光标在当前字符前面;a 进入插入模式后,光标在当
前字符后面
h j k l 分别是光标左移、下移、上移、右移(一般来说你不会用到它们来移动光标,按方向键就可以了)
x 删除一个字符
dd 删除一行
J 删除本行的回车符,把下一行并入本行末尾
r字符 替换光标所在字符为新字符
^ $ 分别是光标移到行首和行末
数字G 移动光标到第若干行,如果直接按 G 则移动到最后一行
:q 退出! (更确切的说应该是关闭当前文件)
:w 文件名 存盘。如果还是保存为当前文件,不必写文件名
:wq 存盘退出
:new 文件名 打开或新建文件(同时关闭当前文件)。如果不指定文件名或者文件名不存在则是新建文件
:help 帮助! 看完后用 :q 关掉窗口。可以在 help 后面加某个帮助主题的名称,如 :help dd 或 :help
help
还有一点是,如果某个命令得到警告(拒绝执行),则要在命令的命令词后加"叹号"表示强制执行
在普通模式下按 v 进入可视模式
x 或 d 剪切(即删除,同时所选的文本进入剪贴板)
y 复制
r字符 所有字符替换为新字符
u U ~ 分别是所有字母变小写、变大写、反转大小写
> < 分别是缩进和反缩进
当输入了命令以后,VIM 将回到普通模式,这时可以按 p 或 P 进行粘贴。普通模式下有关复制和粘贴的命
令:
v 进入可视模式
p 或 P 在当前位置粘贴剪贴板的内容,p 粘在光标所在字符后面,P 粘在前面
/字符串 向下搜索字符串
?字符串 向上搜索字符串
* # 分别是向下和向上搜索光标所指的词
n 重复上一次搜索
:起始行,结束行s/搜索串/替换串/g 从起始行到结束行,把所有的搜索串替换为替换串
:set ignorecase 设置忽略字母大小写。可以用 :set noignorecase 取消忽略字母大小写
搜索字符串用的是正规表达式(Regular expression),其中许多字符都有特殊含义:
\ 取消后面所跟字符的特殊含义。比如 \[vim\] 匹配字符串“[vim]”
[] 匹配其中之一。比如 [vim] 匹配字母“v”、“i”或者“m”,[a-zA-Z] 匹配任意字母
[^] 匹配非其中之一。比如 [^vim] 匹配除字母“v”、“i”和“m”之外的所有字符
. 匹配任意字符
* 匹配前一字符大于等于零遍。比如 vi*m 匹配“vm”、“vim”、“viim”……
\+ 匹配前一字符大于等于一遍。比如 vi\+m 匹配“vim”、“viim”、“viiim”……
\? 匹配前一字符零遍或者一遍。比如 vi\?m 匹配“vm”或者“vim”
^ 匹配行首。例如 /^hello 查找出现在行首的单词 hello
$ 匹配行末。例如 /hello$ 查找出现在行末的单词 hello
\(\) 括住某段正规表达式
\数字 重复匹配前面某段括住的表达式。例如 \(hello\).*\1 匹配一个开始和末尾都是“hello”,中间是
任意字符串的字符串
对于替换字符串,可以用“&”代表整个搜索字符串,或者用“\数字”代表搜索字符串中的某段括住的表达
式。
举一个复杂的例子,把文中的所有字符串“abc……xyz”替换为“xyz……abc”可以有下列写法:
:%s/abc\(.*\)xyz/xyz\1abc/g
:%s/\(abc\)\(.*\)\(xyz\)/\3\2\1/g
* diff 模式
专门用于比较编辑两个或多个内容相近的文件的模式。一般来说,比如你要比较编辑 A 跟 B 两个文件,你
可以命令行启动 vim - d A B 或者这样:先打开文件 A,然后 :vsplit 打开文件 B,对文件 A 和 B 都输
入命令 :diffthis。这时 VIM 将非常清晰的对比显示出两个文件的不同之处,编辑起来十分方便。
2. 折叠代码
可以zf进行折叠, 用zo打开折叠,也可以方向键向右打开折叠, zc关闭折叠(只要在被折叠的块中的任一个语
句就行)
3. 缩进代码
<是左缩进, >是右缩进
按v选定后按=就是自动格式化代码,自动缩进,内部的递归的缩进都做到了
行左移<<,行右移>>,该命令用于调整源码缩进格式简便快速。
4. 移动光标
%是从大括号的开始移动到大括号的结束位置
:后边加行号就是跳到这一行
本文一般情况下用
母,命令前加一个i表示在插入模式下用这个命令
1. 选定文字 / 拷贝粘贴
v为可视模式,可以选定多行。选定多行之后,可以用yy或者dd等等进行拷贝和剪切。
p 是粘贴
y 和d 可以直接拷贝或者剪切选定的内容
yw是拷贝一个单词
如果要复制整行的最简单办法就是V,y,p 就行了
v是可以选定一行任意个字符的,V是行选定的,一次一整行,然后通过向下或向上移动光标而选定多行。
对于v选定的,拷贝后就是这么多,选多少就拷贝多少,而V选定的,粘贴的话会自动换到下一行
2. 多文件编辑 / 缓冲区命令
vim下每一个打开的文件对应一个缓冲区(buffer)。
多文件编辑会有两种情形,一种是在进入 vim 前所用的参数就是多个文件(这种情形称为 argument list
)。另一种情形是进入 vim 后另外再开其它的文件(称为 buffer list)。不过都可以统称为buffer。
2.1 打开文件
vi flname1 flname2… flnameN
将多个文件调入缓冲,是 argument list。
:e filename
这是在进入 vim 后,在不离开 vim 的情形下再开其它文件,只要您要编辑的档案是在目前目录,Tab 补全
键还是可以使用。是buffer list。
注意::e 或者:new 或者:split 后边可以跟目录,这样就可以在目录下慢慢找要打开的文件了
2.2 缓冲区跳转
:n 编辑下一个文件。
:2n 编辑下二个文件。
:N 编辑前一个文件。注意,这种用法只能用于 argument list 的情形。
:rew 回到首文件
:args 查看当前编辑缓冲文件状态
:e# 或 Ctrl-^ 编辑前一个档案,用于两文件互相编辑时相当好用。这种用法不管是 argument list 或
buffer list 档案间皆可使用。 使用Ctrl-^ 命令更便捷,但如终端类型不正确该功能将无效。
用:ls来显示缓冲区中的文件,编号后边有#的代表是前一个文件,可以通过:e#来进入,有%a的代表是当前
文件,什么也没有的可以通过:bn来进入,这里的n代表文件编号。
:b文件名或编号 移至该文件。
在 :ls 中就会出示各文件的编号,这个编号在未离开 vim 前是不会变的。这个指令 elvis 也是可以使用
。当然 :e#编号 也是可以的,这样的用法则是所有 vi clone 都通用了。
在 buffers 中,减号 - 表示这个 buffer 并未载入,不过,不必担心,载入相当快速的。加号 + 表示这
个 buffer 已经修改过了。
:bn buffer next。这里的n代表字母n
:bl buffer last。
以上两个指令 elvis 不适用。
如果您是使用 vim 的 GUI,那就在菜单上就会有 Buffers 这个选项,可以很容易的知道及移动各buffer
间。
2.3 移除缓冲区
:bd(elete) buffer 在未离开 vim 前是不会移除的,可使用这个指令移除。其实移除它干什么呢?vim是
您在叫用时才会载入的,因此这些 buffers 并不是像 cache 一般要占内存的。
2.4 重新编辑
放弃一修改过的文件,重新编辑。
(1)使用命令 :q!强行退出后再vi flname重新进入。
(2)使用命令 :e!强行重编辑更便捷。这样也是会打开文件,但会放弃目前编辑文件的改变,否则如果文件
已有变动,vim 预设是不让您随便离开的。:e! 后不接什么的话,代表舍弃一切修改,重新载入编辑中文件
。
2.5 其他命令
:files 或 :buffers 或 :ls 会列出目前 buffer 中的所有文件。
在 elvis 中可使用 :b 来叫出 buffers。
:f 或 Ctrl-g 显示目前编辑的文件名、是否经过修改及目前光标所在之位置。
:f 文件名 改变编辑中的文件名。(file)
:r 文件名 在光标所在处插入一个文件的内容。(read)
:35 r 文件名 将文件插入至 35 行之后。
gf 这是 vim 的特殊打开文件的方法,会打开光标所在处的 word 为名的文件,当然,这个文件要在当前
目录内,否则会创建新文件。
6. 查找命令
用/查找单词后,n可以跳到下一个,N则是上一个,:nohls可以取消高亮
查找时,:set ignorecase”项让VIM忽略大小写,“:set noignorecase” 来关闭这项功能。
7. 修改文字
cw:删除一个单词并进入插入模式,cc:删除一行并进入插入模式。
r:然后输入的字母将替换当前字母并保持命令模式,R则是不停的替换(一个挨着一个)。
0到行首,$到行尾。
8. 函数间跳转
ctrl+]和ctrl+T分别是查找函数的定义和返回,好像需要ctag的支持
文件,否则找库函数的话还不如man.
大写K 看光标所指标识符的 man 帮助页
9. 窗口命令
:split 文件名 同时在一个页面显示多个文件的内容,类似多窗口,用
的文件
用Ctrl-W命令指定光标移动:
Ctrl-W + 扩大窗口
Ctrl-W - 缩小窗口
Ctrl-W h 移动到窗口左边
Ctrl-W j 移动到窗口下边
Ctrl-W k 移动到窗口上边
Ctrl-W l 移动到窗口右边
等于是
如果要关闭分割窗口可以用:close,剩下只有一个窗口的话就不能关了。
多窗口是split,像用e打开多个文件是将文件放在缓冲区中。
10. 自动完成
i
i
i
比如你写过一行 for (int i = 0; i < 100; i++),你想再写一模一样的一行,只要输入 for
可。如果补全出来的不是你想要的那一行,你可以按 X> 如果按 而文件的位置将在 path 中搜索。 i i 11. 注释整块内容 注释块的方法: I之后输入的东西就是插入到选定的行前边的,直至Esc. 要去掉注释的办法: 列块选定后I是在前边都插入,A是在后边都插入 12. 其他命令 u可以撤销上一步操作, ctrl+r可以恢复 i i . 在光标当前位置处重复上一次操作 :!命令行 执行一条外部命令 vi小技巧 1.*关于退出:* :wq! ----强制保存退出 :wq ---- 保存退出 : x ----- 作用和:wq 一样 ZZ ---- 作用和:wq一样,(注意Z是大写的,并且不是在命令模式) :q ---- 退出 :q! --- 强制退出 ======================================================== 2.*关于移动:* h : 在当前行向左移动一个字符 j: 移动到下一行 k:移动到上一行 l:在当前行向右移动一个字符 Ctrl +f: 向前滚动一页 Ctrl +b:向后滚动一页 :n 将光标定位到第n行 :$ 将光标定位到最后一行 0 将光标定位到本行的行首 $ 将光标定位到本行的行尾 G 将光标定位到本文章的最后一行,与:$功能相同。 H 将光标定位到屏幕的顶端 M 将光标定位到屏幕的中间 L 将光标定位到屏幕的底端 ============================================================= 3.*关于搜索:* /: 后面跟要查找的东西,在文件中向前搜索 ?:后面跟要查找的东西,在文件中向后搜索 n: 向前重复搜索 N: 向后重复搜索 ============================================================= 4.*关于复制* yy: 复制光标当前行 nyy: 复制光标当前行到当前行以下的n-1行 :1,100 co 200 将1~100的内容复制到第200行。 :100,102 co $ 将100~102行的内容复制到最后一行。 ============================================================== 5.*关于粘贴:* p : 粘贴到当前行的下一行 P(大) : 粘贴到当前行的 上一行 ============================================================== 6.*关于删除.剪切:* dd 删除当前行 ndd 与nyy相似 dw 删除一个单词 ndw 与ndd相似 x 删除一个字符 nx 删除n个字符 dG 删除当前光标到文件末尾的所有内容。 d0 删除当前光标到本行行首的所有内容 d$ 删除当前光标到本行行尾的所有内容 :1,100d 删除1~100 :100d 删除第100行 :1,100 mo $ 将1~100行的内容移动到最后一行。 ====================================================== 7.*关于插入:* i: 在当前位置的字符前面进入插入模式 I: 在当前行的开头进行插入 a: 在当前位置的字符后面进入插入模式 A: 在当前行的结尾进行插入 o: 在当前行下面打开一个新行进行插入 O:在当前行上面打开一个新行进行插入 ====================================================== 8.*关于撤销:* u: 撤销上一次的更改 ======================================================= 9.*关于替换: r*egexp:是要匹配的式样 replacement: 是要替换的字符串* *:s /regexp/replacement -------------------------替换当前行出现的第一个式样 :s/regexp/replacement/g-------------------------替换当前行所有的匹配 :%s/regexp/replacement/g-----------------------替换文件中所有匹配式样