1.6 文件与目录基本操作
Linux系统中,文件与目录的操作是最基本、最重要的技术。用户可以方便、高效地通过系统提供的命令对文件和目录进行操作,本节将分别对这些基本命令进行介绍。
1.6.1 显示文件内容
用户要查看一个文件的内容时,可以根据显示要求的不同选用以下的命令。
1.cat命令
该命令的主要功能是用来显示文件,依次读取其后所指文件的内容并将其输出到标准输出设备上。另外,还能够用来连接两个或多个文件,形成新的文件。
该命令的使用形式为:cat[选项]文件名。
下面给出使用该命令的例子:
#cat Readme.txt //在屏幕上显示出Readme.txt 文件的内容 //屏幕上显示出Readme.txt 文件的内容,如果文件中含有特殊字符的话,一起显示出来 #cat - A Readme.txt //把文件test1和文件test2的内容合并起来,放入文件test3中 #cat test1 test2 > test3 //此时在终端屏幕上不能直接看到该命令执行后的结果,也就是文件test3的内容,若想看到连 //接后的文件内容,可以使用“cat test3”命令 #cat test3 //显示文件test3的内容
2.more命令
在查看文件过程中,因为有的文本过于庞大,文本在屏幕上迅速地闪过,故用户来不及看清其内容。而该命令就可以一次显示一屏文本,显示满之后,停下来,并在终端底部打印出- - More- -,系统还将同时显示出已显示文本占全部文本的百分比,若要继续显示,按回车或空格键即可。
该命令的使用形式为:more[选项]文件名。
下面给出示例,说明如何使用上述命令及参数:
//用分页的方式显示文件Makefile的内容 #more Makefile //下面为文件内容 CC = gcc -g # include path hash should be changed. INCLUDES = -I../../include -I/usr/include/pcap -I./include #INCLUDES = -I../../include -I/usr/include/pcap -I../../include CFLAGS = -Wall -Wstrict-prototypes $(INCLUDES) \ 'libnet-config --defines' SOURCES = smtp_ns.c OBJS = $(SOURCES:.c=.o) TARGETS = smtp_ns # this is just for test .PHONY: all clean deps test all: $(TARGETS) clean: rm -f $(TARGETS) *.o core core.* *~ smtp_ns: smtp_ns.c --More--(88%) //文件显示百分比为88%,说明还有部分内容一整屏难以显示 //显示Rules.make文件的内容,但显示之前要先清屏,并且在屏幕的最下方显示完整的百分比 #more - dc example1.c //下面为文件内容 # This file contains rules which are shared between multiple Makefiles. # False targets. .PHONY: dummy # # Special variables which should not be exported # unexport EXTRA_AFLAGS unexport EXTRA_CFLAGS unexport EXTRA_LDFLAGS unexport EXTRA_ARFLAGS unexport SUBDIRS unexport SUB_DIRS unexport ALL_SUB_DIRS unexport MOD_SUB_DIRS unexport O_TARGET unexport ALL_MOBJS --More--(4%)[Press space to continue, 'q' to quit.] //显示COPYING文件的内容,要求每10行显示一次,且显示之前要先清屏。 #more - c -10 COPYING //显示文件的前10行内容 NOTE! This copyright does *not* cover user programs that use kernel services by normal system calls - this is merely considered normal use of the kernel, and does *not* fall under the heading of "derived work". Also note that the GPL below is copyrighted by the Free Software Foundation, but the instance of code that it refers to (the Linux kernel) is copyrighted by me and others who actually wrote it. Also note that the only valid version of the GPL as far as the kernel is concerned is _this_ license (ie v2), unless explicitly otherwise stated.--More--(2%)
3.less命令
该命令的功能和more命令的功能基本相同,也是用来按页显示文件,不同之处在于less命令在显示文件时允许用户既可以向前又可以向后地翻阅文件,而more命令只能向后翻阅文件。由于该命令参数的使用与more命令类似,在此不再赘述。
该命令的使用形式为:less文件名。
如果要向后翻阅,可以使用键盘的“Page UP”键;要向前翻阅文件,则相应地使用键盘的“Page Down”键即可。
4.head命令
该命令只显示文件或标准输入(从计算机的标准输入设备中得到的信息流,通常是指从键盘、鼠标等获得的数据)的头几行内容。如果用户希望查看一个文件究竟保存的是什么内容,只要查看文件的头几行,而不必浏览整个文件,便可以使用这个命令。
该命令的使用形式为:head [n值]文件名。
该命令用来显示每个指定文件的前面n行。如果没有给出n值,默认设置为10。如果没有指定文件,head就从标准输入读取。例如:显示文件test.c的前3行。
#head - 3 test.c //前3行的具体内容 #include <stdio.h> #include <sring.h> int main()
5.tail命令
和head命令的功能相对应。如果想查看文件的尾部,可以使用tail命令。该命令显示一个文件的指定内容。它把指定文件的指定显示范围内的内容显示在标准输出上。同样,如果没有给定文件名,则使用标准输入文件。
该命令的使用形式为:tail [选项]文件名。
例如:
#tail -4 example //显示文件example的最后4行。
1.6.2 文件内容查询
文件内容查询命令主要是指grep、fgrep和egrep命令。这组命令以指定的查找模式搜索文件,通知用户在什么文件中搜索到与指定的模式匹配的字符串,并且打印出所有包含该字符串的文本行,该文本行的最前面是该行所在的文件名。grep命令一次只能搜索一个指定的模式;egrep命令检索扩展的正则表达式(包括表达式组和可选项);fgrep命令检索固定字符串,并不识别正则表达式,是一种更为快速的搜索命令。
这组命令在搜索与定位文件中特定的主题和关键词方面非常有效。可以用其来搜索文件中包含的这些关键词。总的来说,grep命令的搜索功能比fgrep强大,因为grep命令的搜索模式可以是正则表达式,而fgrep却不能。
该组命令中的每一个命令都有一组选项,利用这些选项可以改变其输出方式。例如,可以在搜索到的文本行上加入行号,或者只输出文本行的行号,或输出所有与搜索模式不匹配的文本行,或只简单地输出已搜索到指定模式的文件名,并且可以指定在查找模式时忽略大小写。
这组命令在指定的输入文件中查找与模式匹配的行。如果没有指定文件,则从标准输入中读取。正常情况下,每个匹配的行都被显示到标准输出。如果要查找的文件是多个,则在每一行输出之前加上文件名。该组命令的使用方式如下:
grep [选项] [查找模式] [文件名1,文件名2,……] egrep [选项] [查找模式] [文件名1,文件名2,……] fgrep [选项] [查找模式] [文件名1,文件名2,……]
下面列出常用的部分命令选项:
● - b:在输出的每一行前显示包含匹配字符串的行在文件中的字节偏移量;
● - c:只显示匹配行的数量;
● - i:比较时不区分大小写;
● - h:在查找多个文件时,指示grep不要将文件名加入到输出之前;
● - l:显示首次匹配串所在的文件名并用换行符将其隔开。当在某文件中多次出现匹配串时,不重复显示此文件名;
● - n:在输出前加上匹配串所在行的行号(文件首行行号为1);
● - v:只显示不包含匹配串的行;
● - x::只显示整行严格匹配的行。
下面给出一些使用grep命令的例子,该组其他命令的使用方法和该命令是一样的:
#grep 'text file'stdc.h //在文件stdc.h中搜索字符串“text file” #grep data * //搜索出当前目录下所有文件中含有“data”字符串的行 #grep stdio.h *.c //在C程序文件中搜索包含有“stdio.h”头文件的所有文件
1.6.3 文件查找
用户进行文件查找时,可以使用如下介绍的几种命令。
1.find命令
该命令的功能是在指定的目录开始,递归地搜索其各个子目录,查找满足寻找条件的文件并对之采取相关的操作。此命令提供了相当多的查找条件,功能非常强大。
该命令的使用形式为:find [选项] 文件名。
下面给出使用该命令的例子:
//查找当前目录中所有以main开头的文件,并显示这些文件的内容 #find . - name 'main*' - exec more {} \; //删除当前目录下所有一周之内没有被访问过的a .out或*.o文件 #find . \(- name a.out - o - name '*.o'\)\ > - atime +7 - exec rm {} \; //寻找三个给定条件都满足的所有文件 #find -name 'tmp' -xtype c -user 'inin' //查询文件名为‘tmp’或是匹配‘mina*’的所有文件 #find -name 'tmp' -o -name 'mina*' //命令查询文件名不是‘tmp’的所有文件 #find ! -name 'tmp'
2.locate命令
该命令也用于查找文件,比find命令的搜索速度快。使用时需要一个数据库,这个数据库由每天的例行工作(crontab)程序来建立。建立好数据库后,就可以方便地用来搜寻所需文件了。
该命令的使用形式为:locate [选项] 文件名。
例如,在/usr/src/linux-2.4目录下查找包含有字符串“stdio.h”的所有文件:
#locate /usr/src/linux-2.4 //部分查询所得的文件 /usr/lib/perl5/5.6.0/i386-linux/CORE/nostdio.h /usr/lib/bcc/include/stdio.h /usr/include/isc/stdio.h /usr/include/bits/stdio.h /usr/include/stdio.h /usr/src/linux-2.5.22/arch/ppc/boot/include/nonstdio.h /usr/src/linux-2.5.22/arch/ppc/xmon/nonstdio.h
1.6.4 文本处理
文件处理命令包括sort和uniq,下面分别对其进行介绍。
1.sort命令
该命令的功能是对文件中的各行进行排序。它有许多非常实用的选项,它们最初是用来对数据库格式的文件内容进行各种排序操作的。实际上,sort命令可以被认为是一个非常强大的数据管理工具,用来管理内容类似数据库记录的文件。
该命令将逐行地对文件中的内容进行排序,如果两行的首字符相同,该命令将继续比较这两行的下一字符。sort排序是根据从输入行抽取的一个或多个关键字进行比较来完成的。排序关键字定义了用来排序的最小的字符序列。在默认情况下,以整行为关键字按ASCII字符顺序进行排序。
该命令的使用形式为:sort [选项] 文件名。
下面给出几个使用该命令的例子:
//用sort命令对text文件中各行排序后输出其结果。 #cat text //查看text未排序前原文件内容 //text原文件内容 vegetable soup fresh vegetables fresh fruit lowfat milk #sort text //对该文件进行排序 //显示排序后结果 fresh fruit fresh vegetables lowfat milk vegetable soup //用户可以保存排序后的文件内容,或把排序后的文件内容输出至打印机。下例中用户把排序后的 //文件内容保存到名为result的文件中 #sort text>result //以第2个字段作为排序关键字对文件example的内容进行排序 #sort +1-2 example //对于file1和file2文件内容反向排序,结果放在outfile中,利用第2个字段的第一个字符 //作为排序关键字 #sort -r -o outfile +1.0 -1.1 example //sort排序常用于在管道中与其他命令连用,组合完成比较复杂的功能,如利用管道将 //当前工作目录中的文件送给sort进行排序,排序关键字是第6个至第8个字段 #ls - l | sort +5 - 7
sort命令也可以对标准输入进行操作。例如,如果想把几个文件文本行合并,并对合并后的文本行进行排序,可以首先用命令cat把多个文件合并,然后用管道操作把合并后的文本行输入给命令sort,sort命令将输出这些合并及排序后的文本行。在下面的例子中,文件veglist与文件fruitlist的文本行经过合并与排序后被保存到文件clist中。
#cat veglist fruitlist | sort > clist
2.uniq命令
文件经过处理后在它的输出文件中可能会出现重复的行。例如,用cat命令将两个文件合并后,再使用sort命令进行排序,就可能出现重复行。这时可以用uniq命令将这些重复行从输出文件中删除,只留下每条记录的唯一样本。
该命令的使用形式为:uniq [选项] 文件名。
下面是使用该命令的实例:
#uniq -u example //显示文件example中不重复的行 //显示文件example中不重复的行,从第2个字段的第2个字符开始做比较。 #uniq - u -1 +1 example
1.6.5 文件内容统计
文件内容统计命令主要是指wc命令。该命令统计给定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所有指定文件的总统计数。字是由空格字符区分开的最大字符串。
该命令的使用形式为:wc [选项]文件名。
下面给出使用该命令的例子:
//统计文件README的行数、字节数和字数 #wc -lcw README 303 2265 14242 README //对文件README和README.freeswan进行行数、字节数、字数的统计 #wc -lcw README README.freeswan 303 2265 14242 README 174 766 5585 README.freeswan 477 3031 19827 total
1.6.6 文件比较
Linux系统中可以使用comm和diff命令比较文件的异同,下面分别对这两个命令进行介绍。
1.comm命令
该命令是对两个已经排好序的文件进行比较。其中file1和file2是已排序的文件(如果没有,可以使用上述的sort命令先进行排序)。comm读取这两个文件,然后生成三列输出:仅在file1中出现的行;仅在file2中出现的行;在两个文件中都存在的行。如果文件名用“-”,则表示从标准输入读取。
该命令的使用形式为:comm [选项]文件名。
选项1、2或3控制相应的列显示与否。例如comm - 12就只显示在两个文件中都存在的行;comm - 23只显示在第一个文件中出现而未在第二个文件中出现的行;comm - 123则什么也不显示。下面给出使用该命令的例子:
//对文件app.c和app1.c进行比较 #cat app.c //待比较文件app.c内容 #include <stdio.h> #include <string.h> #include <stdlib.h> void main() { int count = 0; printf("hello,world!\n"); } //显示待比较文件app1.c内容 #cat app1.c #include <stdio.h> #include <string.h> void main() { int count ; char *s = "hello,world"; printf("hello,world!\n"); } //对上述文件进行比较,显示两个文件中共有行的内容 #comm -12 app.c app1.c #include <stdio.h> #include <string.h> void main() { printf("hello,world!\n"); } //对上述文件进行比较,显示在第一个文件中出现,而在第二个文件中不出现的内容 #comm -23 app.c app1.c #include <stdlib.h> int count = 0;
2.diff命令
该命令的功能为逐行比较两个文本文件,列出其不同之处。它对给出的文件进行系统地检查,并显示出两个文件中所有不同的行,不要求事先对文件进行排序。
该命令的使用形式为:diff [选项]待比较文件1待比较文件2。
该命令运行后的输出通常由下述形式的行组成:
n1 a n3,n4 n1,n2 d n3 n1,n2 c n3,n4
以上说明如何将file1转变成file2,从而给出了两个文本文件之间的差异。其中,字母(a、d和c)之前的行号(n1,n2)是针对file1的,其后面的行号(n3,n4)是针对file2的。字母a、d和c分别表示附加、删除和修改操作。
在上述形式的每一行的后面跟随受到影响的若干行,以“<”打头的行属于第一个文件,以“>”打头的行属于第二个文件。
如果file1和file2都是目录,则diff会产生很多信息。如果一个目录中只有一个文件,则产生一条信息,指出该目录路径名和其中的文件名。
下面给出使用该命令的例子:
//对文件app.c和app1.c进行比较 #cat app.c //待比较文件app.c内容 #include <stdio.h> #include <string.h> #include <stdlib.h> void main() { int count = 0; printf("hello,world!\n"); } //显示待比较文件app1.c内容 #cat app1.c #include <stdio.h> #include <string.h> void main() { int count ; char *s = "hello,world"; printf("hello,world!\n"); } //使用diff比较得出上述两个文件的不同之处 #diff app.c app1.c 3d2 < #include <stdlib.h> 6c5,6 < int count = 0; --- > int count ; > char *s = "hello,world";
上述结果表示把文件app.c的第3行“#include <stdlib.h>”删除,并修改app.c文件的第5行“int count = 0;”和app1.c文件的第五行“int count ;”、第6行“char *s = "hello,world";”后,则两个文件相同。
1.6.7 文件的复制、移动和删除
文件的复制、删除和移动操作在Linux系统中使用得非常频繁,下面对这些操作的命令进行详细介绍。
1.cp命令
该命令的功能是将给出的文件或目录拷贝到另一文件或目录中,就如同DOS下的copy命令一样,功能非常强大。
该命令的使用形式为:cp [选项]源文件或目录目标文件或目录。
下面举例说明该命令的使用:
//将文件exam1.c拷贝到/usr/wang目录下,并改名为 shiyan1.c #cp - i exam1.c /usr/wang/shiyan1.c //若不希望重新命名,可以使用下面的命令 #cp exam1.c /usr/ wang/ //将/usr/xu目录中的所有文件及其子目录拷贝到目录/usr/liu中 #cp - r /usr/xu/ /usr/liu/
2.mv命令
用户可以使用mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中。该命令如同DOS下的ren和move的组合。
该命令的使用形式为:mv [选项] 源文件或目录 目标文件或目录
下面举例说明该命令的使用:
//将/usr/xu中的所有文件移到当前目录(用“.”表示)中 #mv /usr/xu/ * . //将文件wch.txt重命名为wjz.doc #mv wch.txt wjz.doc
3.rm命令
在Linux中创建文件很容易,系统中随时会有文件变得过时且毫无用处。用户可以用rm命令将其删除。该命令的功能为删除一个目录中的一个或多个文件,它也可以将某个目录及其下的所有文件及子目录均删除。对于链接文件,只是删除了链接,原有文件均保持不变。
该命令的使用形式为:rm [选项]文件。
在下一个例子中,用户想要删除文件test和example。系统会要求对每个文件进行确认。用户最终决定删除example文件,保留test文件。
#rm -i test example Remove test ?n Remove example ?y
1.6.8 文件链接
文件链接命令是指ln命令。该命令在文件之间创建链接。这种操作实际上是给系统中已有的某个文件指定另外一个可用于访问它的名称。对于这个新的文件名,我们可以为其指定不同的访问权限,以控制对信息的共享和安全性的问题。
如果链接指向目录,用户就可以利用该链接直接进入被链接的目录而不用使用较长的路径名。而且,即使我们删除这个链接,也不会破坏原来的目录。
链接有两种,一种被称为硬链接(Hard Link);另一种被称为符号链接(Symbolic Link),也称为软链接。建立硬链接时,链接文件和被链接文件必须位于同一个文件系统中,并且不能建立指向目录的硬链接。而对符号链接,则不存在这个问题。默认情况下,ln产生硬链接。
在硬链接的情况下,参数中的“目标”被链接至[链接名]。如果[链接名]是一个目录名,系统将在该目录之下建立一个或多个与“目标”名的链接文件,链接文件和被链接文件的内容完全相同。如果[链接名]为一个文件,用户将被告知该文件已存在且不进行链接。如果指定了多个“目标”参数,那么最后一个参数必须为目录。
如果给ln命令加上- s选项,则建立符号链接。如果[链接名]已经存在但不是目录,将不做链接。[链接名]可以是任何一个文件名(可包含路径),也可以是一个目录,并且允许其与“目标”不在同一个文件系统中。如果[链接名]是一个已经存在的目录,系统将在该目录下建立一个或多个与“目标”同名的文件,此新建的文件实际上是指向原“目标”的符号链接文件。
该命令的使用形式为:ln [选项] 目标 [链接名]。
下面举例说明该命令的使用:
//用户为当前目录下的文件lunch创建了一个符号链接/home/xu #ln - s lunch /home/xu //使用建立的软链接查看文件,实际查看的是原文件lunch的内容 #cat /home/xu
1.6.9 目录的创建与删除
下面介绍Linux系统中目录的创建以及删除命令的使用。
1.mkdir命令
该命令创建由dirname命名的目录。要求创建目录的用户在当前目录中(dirname的父目录中)具有写权限,并且dirname不能是当前目录中已有的目录或文件名称。
该命令的使用形式为:mkdir [选项] dirname
例如:在当前目录中建立inin和inin下的/mail目录,也就是连续建两个目录。
#mkdir - p - m 700 ./inin/mail/
该命令的执行结果是在当前目录中创建嵌套的目录层次inin /mail,权限设置为只有文件所有者有读、写和执行权限。
2.rmdir命令
该命令的使用形式为:rmdir [选项] dirname
dirname表示目录名。该命令从一个目录中删除一个或多个子目录项。
需要注意的是,一个目录被删除之前必须是空的。删除某目录时也必须具有对父目录的写权限。
例如要将/usr/xu/txt目录删除,命令如下:
#rmdir - p /usr/xu/txt
1.6.10 改变工作目录、显示路径及显示目录内容
Linux系统分别使用cd、pwd以及ls命令来改变工作目录、显示路径以及显示目录的内容,下面对这些命令进行介绍。
1.cd命令
该命令的使用形式为:cd [directory]。
该命令将当前目录改变为directory所指定的目录。若没有指定directory,则回到用户的主目录。为了改变到指定目录,用户必须拥有对指定目录的执行和读权限。该命令可以使用通配符。
假设用户当前目录是:/home/working,若要更换到/usr/src目录中,则使用如下命令:
#cd /usr/src
2.pwd命令
该命令的使用形式为:pwd。
在Linux层次目录结构中,用户可以在被授权的任意目录下用mkdir命令创建新目录,也可以用cd命令从一个目录转换到另一个目录。然而,没有提示符来告知用户目前处于哪一个目录中。要想知道当前所处的目录,可以用pwd命令,该命令显示整个路径名。
例如使用该命令显示当前工作路径,命令如下:
#pwd /home/working