这是一篇适合于没有任何基础的初学者学习Cent OS常用命令的博客,努力看看能不能写成一个系列博客。有时,我们需要的只是一道小小的缝隙,让我们有个支点去打开一扇厚重的门。

八、文件的操作

前面的touch命令,只是Linux中一条简单的文件创建命令。文件的操作不但包括创建、删除等,还包括浏览、修改等操作,这些都是学习Linux必学的内容,因为Linux的配置文件或者是Shell编程、程序设计是经常要用到这些工具的。

Linux提供的文件编辑命令很多也很强大,对于初学者来说,重点要掌握vi、cat、more、less、head、tail、grep这些命令的操作。

(1)vi

CentOS 6.5默认安装下的vi其实就是vim的别名。通过which查看vi命令可知。

[Bob@firstlinux~]$ which vi

aliasvi='vim'

    /usr/bin/vim

因此,在CentOS 6.5中使用命令vi与vim一样,其实是都是调用vim。

vi与vim的关系可以理解为:vim是vi的加强版本(初学者先这样理解吧,不大对就是了)。vim不但兼容vi的指令,且功能更加强大。初学者不用纠结于vi与vim之间有多大区别,先从一些简单的操作入手,这些操作vi与vim是兼容的。

使用vi创建文件

使用vi创建文件,可以只输入命令vi或者输入vi 文件路径+文件名。

当只输入vi时,是打开vi程序,新建一个未命名的文件。

当输入vi跟上文件路径+文件名时,可以在指定目录中创建一个指定文件名的文件,如果文件路径没有加,则在当前目录创建一个指定文件名的文件。

两种方式的创建其实在磁盘上文件都还不存在,要在后续使用保存命令保存后才算在磁盘上建立,如果不保存,则没有。

使用:vi 文件名  的方式,如果文件存在,相当于使用vi打开文件。

先试一试,对vi有个大体上的认识:

输入vihello.c,进入后再按i,在vi中输入以下内容:

/*main*/

voidmain()

{

  /*define*/

  char c1,c2;

  c1='a';

  c2='b';

  c1=c1-32;

  c2=c2-32;

  /*print*/

  printf("%c %c",c1,c2);

}

按Esc键,输入:wq。

注意:在输入时,代码行不是使用tab键空出,而使用前面使用两个空格空出(后面查询时会把这个文件当样板用)。

上面例子,先使用vihello.c在当前目录中创建文件hello.c,进入vi编辑器后,按i键表示进入编辑模式,输入内容后按Esc表示退出编辑模式,输入:wq表示保存并退出vi(其中w代表保存,q代表退出)。

②vi的三种模式

vi有三种模式,分别是:命令模式、编辑模式(也称插入模式)、末行模式(底行模式)。其实命令模式与末行模式之间差别并不大,在命令模式输入:就是表示进入末行模式。

光标的定位

vi一开始运行时是处于命令模式下,在命令模式下定位光标的方法有:

可以使用h(左),j(下),k(上),l(右)或上、下、左、右的方向键来移动光标;

可以按shift+g,直接将光标移动到文件最后一行第一个符号位置(前面有空格跳过);

可以按两次的g,直接将光标移动到文件第一行第一个符号位置(前面有空格跳过);

可以输入一个非0阿拉伯数字再按两次g,直接将光标移动阿拉伯数字对应的行第一个符号位置(前面有空格跳过);

可以按0,直接将光标移动到当前行的最前位置(空格也算);

可以输入$,直接将光标移动到当前行的最后位置(空格也算);

模式切换

Esc键是退出编辑模式进入命令模式和末行模式的按键,要从命令模式或末行模式进入编辑模式可选的方式比较多:

按i键在当前光标前进入编辑模式;

按shift+i键在当前光标行首进入编辑模式;

按a键在当前光标后进入编辑模式;

按shift+a键在当前光标行行末进入编辑模式;

按o键在当前光标行的下面新增一行开始编辑;

按shift+o键在当前光标行的上面新增一行开始编辑;

按r键再输入字符会替换当前光标位置的字符继续编辑;

按shift+r键再输入字符会替换当前光标位置与其后的字符,直到按Esc键结束;

对于初学者可以不要记忆太多,记住按i键可进入编辑(且为插入)模式就可以了。

复制、粘贴、删除、撤消、重做、查找

在文件编辑过程中,复制、粘贴、删除、撤消、重做、查找可以说是最常用的操作了,在vi中这些操作要在命令模式下完成。

复制常见操作有两种:按两次yy,复制光标所在行到缓冲区(缓冲区可以理解成windows中的剪贴板);输入阿拉伯数字再按两次yy,复制光标所在行与这行下的阿拉伯数字-1行的内容到缓冲区。

粘贴操作:按p将缓冲区内容粘贴到当前光标所行的下面一行。

删除常见操作有两种:按两次d删除当前光标所在行;输入阿拉伯数字再按两次dd,删除光标所在行与这行下的阿拉伯数字-1行的内容。

撤消操作:按u

重做操作:按.

查找操作有两种:输入/后面接要查找的字符(正向查找);输入?后面接要查找的字符(反向查找)。如果要继续就按n键,如果退出查找输入:noh(一条末行模式的命令)。

常见末行模式的命令

命令

功能

:n1,n2s/w1/w2/g

将n1到n2行中的w2替换成w1

:g/w1/s//w2/g

将文中全都的w2替换成w1

:set nu

显示行号

:set nonu

不显示行号

:noh

关闭查询

:q

退出文件,如果修改但没保存要用q!或wq

:q!

不保存强制退出

:w

保存文件

:wq

保存强制退出

:r 文件名

将文件名对应的文件读取到当前光标下面行

:w 文件名

将文件另存为文件名的文件,当前编辑文件没有变,还是原来的文件,即相当复制一份文件出来另存。

:w >>文件名

将当前文件添加到指定文件后面

多窗口编辑文件

如果一次要打开多个文件,怎么办?

例1:一次性打开两个文件,纵向排列

vi -o 文件1 文件2

例2:一次性打开两个文件,横向排列

vi -O 文件1 文件2

即:-o是纵向排列,-O是横向排列;要打开几个文件就在后面罗列几个文件名(中间空格格开)。

如果打开多个文件,怎么样判断当前正在处理的文件,怎么切换呢?如果要切换可以按住ctrl再按两次w就可以依次的切换要处理的文件,当前在处理的文件下面的文件名字体是粗体。

例3:在已打开文件后,要再同时打开一个文件

在纵向方向打开       sp 文件名

在横向方向打开       vsp 文件名

(2)cat查看文件

要查看文件直接使用cat命令后面空格加文件名,如果多个文件,则文件名之间用空格分开。例如:

cathello.c file2

上面命令同时查看hello.c与file2两个文件,显示hello.c后面直接跟着file2的内容。如果要显示行号,加参数-n(不管有多少个文件,行号都是连续编号)。

使用cat浏览文件,如果文件内容多的话会滚动,只能看到一屏。所以,对于文件内容比较多的文件查看,这种方式并不便利。如果要分屏,一屏一屏的看,要使用more或less。

(3)more与less命令

more与less命令比cat命令改进的地方是:如果内容超过一屏会以分屏显示,当按enter键时会一行一行显示出来,按space键时,会一屏一屏显示出来。如果中间不想浏览了,直接按q键就可以退出。

more命令有进度显示(查看了多少百分比),less命令没有进度显示。

more与less命令在查看上虽然比cat改进了很多,但是有时要查看的只是文件的开头几行或最后增加的几行,这时就要使用命令head或tail。

(4)head或tail命令

①head命令指定显示一个文件开头几行,不加参数,默认显示是10行,格式:

head -n文件名            

-n表示要显示n行,不加默认10行

②tail命令与head类似,指定显示一个文件最后几行,不加参数,默认显示是10行,格式:

tail-n 文件名

-n表示要显示n行,不加默认10行。

(5)强大的grep命令

grep全称globalregular expression print。它的作用是在不打开文件的情况下,根据设定的条件,查找出满足条件的行并显示满足条件的行。

以前面的hello.c文件为例,进行查找。

例1:查找包含printf的行

[Bob@firstlinux~]$ grep 'printf' hello.c

  printf("%c %c",c1,c2);

''内表示要查找的内容。

例2:查找包含/*注释的行,并显示出其行号

[Bob@firstlinux~]$ grep -n '/\*' hello.c

1:/*main*/

4:  /*define*/

10:  /*print*/

''内的*前面要加上\,表示转义,参数-n表示显示行号。

例3:查找不包含/*注释的行

[Bob@firstlinux~]$ grep -v '/\*' hello.c

voidmain()

{

  char c1,c2;

  c1='d';

  c2='b';

  c1=c1-32;

  c2=c2-32;

  printf("%c %c",c1,c2);

}

加上参数-v表示查找不包括表示式中内容的行。

例4:计算包含字符printf的行数

[Bob@firstlinux~]$ grep -c 'print' hello.c

2

查询结果是个数值,加参数-c是统计符合查询的条件的行数。

例5:查询当前目录下hello.c file2 file3三个文件中包含printf的行,并显示行号

[Bob@firstlinux~]$ grep -n 'printf' hello.c file2 file3

结果略...

如果对多个文件进行查询,将文件依次罗列并以空格格开。

例6:对当前目录下文件名包含e字符的所有文件查询包含printf的行,并显示行号

[Bob@firstlinux~]$ grep -n 'printf' *e*

结果略...

在查询范围中,如果文件名不确定,可以使用通配符。通配符中最常用的是?和*,?代表一个字符,*代表任意个字符。

例7:查询hello.c文件中前三个字符不是空格、空格、c组成的行,并显示行号

[Bob@firstlinux~]$ grep -nv "^\ \ c" hello.c

1:/*main*/

2:voidmain()

3:{

4:  /*define*/

10:  /*print*/

11:  printf("%c %c",c1,c2);

12:}

参数-n与-v合并成-nv,^表示行的开始,前两个空格使用转义字符\+空格来表示空格字符。

例8:在查询前先在hello.c第七行下面添加一行,内容为Case。不区分大小写查询hello.c文件中前三个字符是空格、空格、c组成的行,并显示行号。

[Bob@firstlinux~]$ grep -in '^\ \ c' hello.c

5:  char c1,c2;

6:  c1='d';

7:  c2='b';

8:  Case;

9:  c1=c1-32;

10:  c2=c2-32;

不区分查询关键字的大小写,要加参数-i。上面参数-i与-n合并写成-in。

例9:查询hello.c文件中最后两个字符为';的行,并显示行号

[Bob@firstlinux~]$ grep -n "';$" hello.c

6:  c1='d';

7:  c2='b';

如果查询中的内容包含',要查询的字符串可以改成使用""包含,反之也一样。如果要查询的是一行的最后几个符号在查询字符串后面加$。$表示行的结束。

例10:查询行中包含以m开始再间隔两个字符后为n的行,并显示行号

[Bob@firstlinux~]$ grep -n 'm..n' hello.c

1:/*main*/

2:voidmain()

.表示必须有一个任意字符。

例11:查询包含有p或v两个字符中的一个的行,并显示行号

[Bob@firstlinux~]$ grep -n '[pv]' hello.c

2:voidmain()

11:  /*print*/

12:  printf("%c %c",c1,c2);

其中[pv]表示行中要包含有p或v两个字符中的一个。

例12:查询包含有从h至j之间(含h与j)字符的行,并显示行号

[Bob@firstlinux~]$ grep -n '[h-j]' hello.c

1:/*main*/

2:voidmain()

4:  /*define*/

5:  char c1,c2;

11:  /*print*/

12:  printf("%c %c",c1,c2);

例13:查询前先进行如下操作

[Bob@firstlinux~]$ mkdir testone/subtest -p

[Bob@firstlinux~]$ cp hello.c testone/a.c

[Bob@firstlinux~]$ cp hello.c testone/subtest/b.c

如果要查询出testone目录(包含子目录)下所有包含有print字符的文件,则:

[Bob@firstlinux~]$ grep -rl "print" testone

testone/a.c

testone/subtest/b.c

其中r参数表示递归,l参数表示只显示文件名,如果不加l参数,则查询结果为:

[Bob@firstlinux~]$ grep -r "print" testone

testone/a.c:  /*print*/

testone/a.c:  printf("%c %c",c1,c2);

testone/subtest/b.c:  /*print*/

testone/subtest/b.c:  printf("%c %c",c1,c2);

例14:如果要查询包含main或print两个单词的行,并显示行号,则

[Bob@firstlinux~]$ grep -n -e "main" -e "print" hello.c

1:/*main*/

2:voidmain()

11:  /*print*/

12:  printf("%c %c",c1,c2);

上面的查询,如果要查询的单词更多,可以将单词做成一个文件,每行一个,进行查询。比如,先创建要查询单词的文件vi pattern,在文件中输入以下三行

main

print

case

下来查询hello.c文件中包含pattern文件中三行单词的行,并显示出行号,操作如下:

[Bob@firstlinux~]$ grep -n -f pattern hello.c

1:/*main*/

2:voidmain()

11:  /*print*/

12:  printf("%c %c",c1,c2);

[Bob@firstlinux~]$ grep -in -f pattern hello.c

1:/*main*/

2:voidmain()

8:  Case;

11:  /*print*/

12:  printf("%c %c",c1,c2);

两条命令都使用-f这个参数后面加要查询单词存放的文件名,以这文件内每行的单词为查询字符串进行查询。

第一条命令少个参数i,所以少了第8行。(加i参数不区分大小写)。

 

(第三篇 完  待续...)