花两周时间玩玩Linux - Day 3:vi基本操作
花两周时间玩玩Linux - Day 3:vi基本操作
众所周知,vi是一款非常难用的命令行文本编辑器。但是不学vi怎么能说自己玩过Linux🐧呢?
vim:Vi IMporved,升级版vi,不过我们现在只介绍基本功能。
1.模式
"有一个困扰了人们多年的问题:如何退出vim?"🐶
Vi默认模式是命令模式,键盘输入命令,对文本进行操作。在插入模式下,输入的字才写进文本里。
2. vi插入模式
打开编辑器自然是想输入文本了,但是第一次用vi就很尴尬,因为你敲键盘,一个字也没打上(那你去用nano啊!🐶)。
🍍按i进入插入模式(insert mode),然后就可以写了
🍍按a也可,a代表append
🍍按o表示新开(open)一行,另起一行,切换到插入模式
🍍按大写O也是新开一行,但是跑得本行的上一行新开。(记住这个特性,vi的功能设计很多都是这样的,大写的功能和小写反着来)
3. vi命令
1.:set 命令
对编辑器进行设置。例如:
显示行号:
:set number
去掉行号:(原来命令前面加个no就行了)
:set nonumber
显示所有设置的状态:
:set all
2.光标移动
这个非常简单,方向键就能上下左右移动。但是vi发明的年代,作者的键盘没有方向键,方向键和HJKL共用。没办法,vi中HJKL代表左下上右。
数字+按键,可以把这个按键代表的命令重复多次,由数字指定次数。
例如:23j下移23行。
翻页:
Ctrl+B (Backward)后翻一页
Ctrl+F (Forward)前翻一页
Ctrl+U (Page Up)前翻半页
Ctrl+D (Page Down)后翻半页
光标到行尾: $ 行首:^ (还记得正则表达式的首尾匹配符吗?)
按单词移动:w和W移动到下一个单词;b和B移动到上一个单词。
大小写的区别是:
小写的单词是:非字母、数字、下划线的字符都算单词分隔符;(这不就是C语言变量的要求吗)
大写的要求是:只有whitespace算单词分隔符。
举例:1.2
小写认为1是一个词,2是一个词。大写认为1.2是一个词。
移到指定的行::n,n是行号。比如,移到第12行::12
文件尾行用$表示。
那首行呢?是^吗?不是,是1呀!😝
还可以做加减。例::$-10 倒数第10行。
用.表示当前行。例::.+10 后移10行。
用%做括号匹配。如果你的光标在一对括号中的一个上,那么按下%可以使光标跳到另一半括号上。
Mark。vi提供a-z共26个mark供你标记使用。在一个地方按下m,再按下a-z任意字母,这里就被标记了。例如:ma。使用单引号'跳转到mark位置。例如:'a。
3. 文字操作
删一个字:x ; 删100个:100x
删一行:dd ; 删100行:100dd
从光标处删到书签e处:d'e
从光标删到行尾:d$ ; 从光标删到行首: d^
删一个单词:dw
删一对括号以及里面的内容:d%
替换一个字:r + 要替换的一个字
一直替换(进入替换模式):R ,Esc退出
取消:u(undo)
合并(join) J:把下一行并到本行后面
l1,l2d:删掉l1-l2行。
l2,l2col3:把l1-l2行复制到l3行后面。
l1,l2ml3:把l1-l2行移动到l3行。
剪贴板
vi里有一个通用剪贴板和26个命名剪贴板。当你删除内容时,删掉的内容进入剪贴板,用命令p 粘贴。用双引号"+[a-z]标记一个命名剪贴板。例如:
"al1,l2d :删掉l1-l2行,内容放进剪贴板a
把所有带d的命令中的d换成y(yank,抽取),就可以只复制到剪贴板而不删除原内容。例如:
"al1,l2y :复制l1-l2行,内容放进剪贴板a
3yy:复制接下来3行的内容到通用剪贴板。
4.文件命令:
存盘退出:ZZ , :wq
存盘不退出::w 退出不存盘::q!
写文件::l1,l2w filename 把第l1行到第l2行写到文件filename中。行号省略表示整个文件。
5.格式查找与格式替换 🍦
我们的老朋友:正则表达式。
用法:
🍍 /pattern
查找符合模式的位置,按n跳转到下一个,按N跳转到上一个。
🍍 :l1,l2s/pattern/sub-string/g
在l1-l2中间,搜索pattern,把pattern位置都换成sub-string
行号可以省略,省略表示全文。
sub-string中可出现特殊字:&,表示被匹配的字。
多处匹配:用\(和\)括住需要提取的匹配项,在sub-string中以\n表示,n是第n个匹配元素。\0表示全部匹配元素,因此和&等价。
🎃 vi这么难用,我当然不会逼你用。但是这么经典,不得不介绍一下。
Day 2 习题参考答案:
- 统计你的工作目录下,扩展名为txt或pdf或xlsx或docx或没有扩展名的文件或文件夹有几个。
$ ls | egrep "\.(txt|pdf|xlsx|docx)$" | wc -l
- strcpy函数在头文件string.h的哪一行出现了?(include头文件放在
/usr/include目录下)
$ grep strcpy /usr/include/*.h
/usr/include/string.h:extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
$ cat /usr/include/string.h -n | grep strcpy
121 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
- 用awk实现如此打印效果:
+------------------------------+
|This file is printed using awk|
+------------------------------+
+ Happy king was voted
* the most vicious
+ person in the
* world
+------------------------------+
| The end |
+------------------------------+
编写awk脚本,保存为awk.awk:
(如果你用nano或者vim,并且保存为.awk,你会惊喜地看到代码颜色高亮!)
$ nano awk.awk
然后输入这样的脚本:
BEGIN { printf("+------------------------------+\n|This file is printed using awk|\n+------------------------------+\n"); }
END { printf("+------------------------------+\n| The end |\n+------------------------------+"); }
NR % 2 == 1 { printf("+ %s",$0); }
NR % 2 == 0 { rintf("* %s",$0); }
使用awk:
$ awk -f awk.awk arg.c
+------------------------------+
|This file is printed using awk|
+------------------------------+
+ #include<stdio.h>
* int main(int argc,char** argv){
+ int i;
* for(i = 0; i < argc; i++) printf( "%d: [%s]\n",i,argv[i] );
+ }
+------------------------------+
| The end |
+------------------------------+
4.用tr实现凯撒密码。
凯撒密码是把字母表旋转,例如每个字母变成后一个字母。A变成B,B变C,...,Z变A。
$ cat awk.awk | tr '[a-z]' '[A-Z]' | tr '[A-Y]' '[B-Z]' | tr 'Z' 'A' | tee c.txt
CFHJO { QSJOUG("+------------------------------+\O|UIJT GJMF JT QSJOUFE VTJOH BXL|\O+------------------------------+\O"); }
FOE { QSJOUG("+------------------------------+\O| UIF FOE |\O+------------------------------+\O");
}
OS % 2 == 1 { QSJOUG("+ %T\O",$0); }
OS % 2 == 0 { QSJOUG("* %T\O",$0); }
tee把文件写到c.txt了。现在解密:
$ cat c.txt |tr 'A' 'Z' | tr '[B-Z]' '[A-Y]'
BEGIN { PRINTF("+------------------------------+\N|THIS FILE IS PRINTED USING AWK|\N+------------------------------+\N"); }
END { PRINTF("+------------------------------+\N| THE END |\N+------------------------------+\N");
}
NR % 2 == 1 { PRINTF("+ %S\N",$0); }
NR % 2 == 0 { PRINTF("* %S\N",$0); }
🎃怎么样,爱上命令行了吗?明天我们会介绍Linux的文件管理。

浙公网安备 33010602011771号