Unix的轻巧“约取而实得”(中篇)
三、与查找比较相关的命令
使用Windows系统的用户可能都有这样的经历,在网上看到可悠长品赏的电影,down;看到匠心独运的电子书,down;看到妙织锦绣的文章, down;看到衔华佩实的资料,down。但时间一长,想再回顾一下《星战前传3:西斯的反击》中奥比旺和阿纳金在熔岩横流的穆斯塔法星上展开光剑对决的精彩片段,或者是重温一下李开复先生给中国学生第四封信中所提出在大学校园应当掌握的“七项学习”,可能自己都记不清当时是放在哪个目录里了。幸好, Windows为我们提供了“搜索”功能,再加上现今Google、百度相继推出的Google 桌面搜索、百度硬盘搜索,才使得这些文件幸免于藏身深宫大院之中,茕茕孑立、形影相吊的命运。那么在Unix系统中的文件又是怎样的命运呢?且看以下的命令功能:
(一)利用find命令查找文件
find命令的功能是在指定目录及其子目录下查找符合条件的文件,命令格式如下:
find path expression
参数path指欲开始查找的起始目录,find会遍寻此目录以及其子目录,并且此参数可以有多个目录名称,只要在目录与目录之间用空格分开即可。参数 expression指明了诸如基于文件名、文件类型、文件所有者、最后一次修改时间等的查找规则,find命令将遵循此查找规则来查询指定目录以及子目录中的文件。
常用的查找规则如下:
-name filename
|
指定要寻找的文件或目录名称
|
-print
|
将搜索到的符合条件结果以包含路径名的方式输出
|
-type x
|
以文件类型作为寻找条件,常用的文件类型x如下:
d --- 目录文件, f --- 普通文件, b --- 块设备文件, c --- 字符设备文件, l --- 链接文件
|
-user user
|
寻找用户user所拥有的文件,user可为用户名或uid号
|
-atime n
|
寻找n天之前曾被访问过的文件
|
-mtime n
|
寻找n天之前曾被修改过的文件
|
-exec command {}/;
|
用寻找到的文件作为执行command的对象,{}中保存执行command时所需的参数,注意必须以 /; 为结束
|
下面来看一些具体的查找实例:
[例1] 在目录/home中查找名为javac的文件,并要显示出完整的路径名:
find /home –name javac -print
[例2] 在当前目录下查找以doc开头,7天之前曾被修改过的文件:
find . –name “doc*” -mtime 7
[例3] 在目录/home中查找名为anray的目录,并显示出完整的路径:
find /home –name anray –type d -print
[例4] 在目录/home中查找用户zcl所拥有的普通文件,并将其删除:
find /home –type f –user zcl -exec rm {} /;
(二)使用grep命令查找字符串
使用grep命令在文本文件中查找指定的字符串,并将所有出现该字符串的行打印显示出来。grep命令的格式如下:
grep [-iv] 字符串 文件名
参数i代表查找字符串时忽略字母大小写,参数v显示出所有不包含指定字符串的行。如果在欲查找的字符串中包含有空格,那么应该用单引号将此字符串引起来。此外,如果是想同时在多个文件中查找指定的字符串,那么只需列出所有欲搜索的文件即可,这样grep命令会在所列出的匹配行前加上文件名。grep常与通配符、管道符一起搭配使用,这样可以实现一些特殊的查找功能,大家应能结合上面所介绍的命令来综合应用。
[例1] 在文件file1中查找字符串“Java Web”,并忽略大小写。
grep –i ‘Java Web’ file1
或 cat file1 | grep –i ‘Java Web’
或 grep –i ‘Java Web’ < file1
[例2] 在当前目录中查找5月1日创建或修改过的文件。
ls –la | grep –i ‘may 1’
(三)比较两个文件的内容
在Windows系统中,不知你是否用过一款名为WinMerge的软件?此款软件一项非常强悍的功能,就是可以比较两个文件的内容有哪些不同之处,而且可谓是火眼金睛。记得笔者读研一的时候,听一位助教说他就是靠这款软件逮了不少抄袭作业的人:)而在Unix系统中,则无需借助第三方软件就可实现此项功能了。cmp命令可用于比较两个文件,这两个文件可以是文本文件也可以是非文本文件。在默认情况下,cmp命令会显示两个文件第一次数据不同的位置;若两个文件内容相同,则不显示任何信息。cmp命令的格式如下:
cmp [-l] 文件名1 文件名2
参数l代表标示出每个不同之处内容的行号。
另外,还可以使用diff命令来比较两个文本文件或目录的不同之处,它会详细的列出文件1比文件2增多的内容、减少的内容以及改变了的内容。diff命令的格式如下:
diff [-r] 文件1 文件2 //如果比较两个目录的不同之处,加上参数r
在得到的结果中,d表示文件1比文件2增多的内容,a表示文件1比文件2减少的内容,c表示文件1较文件2改变了的内容。
(四)使用wc命令进行统计
大家一看到wc这个词,不知道是否会产生方便的感觉,呵呵。在Unix系统中,wc可是个非常有用的命令。对于Word中的字数统计功能,大家应该非常熟悉,利用它可以统计出一篇文章中的页数、字数、字符数、行数等信息。而wc命令也同样实现了类似于Word的字数统计的功能,它把一个文件作为数据流读入,然后计算出此文件中的行数、单词数以及字符数,并输出这些统计数据。wc命令的格式如下:
wc [-lwc] filename(s)
参数l代表统计行数,参数w代表统计字数,参数c代表统计字符数。
wc -l file1 file2 //统计文件file1和file2 的行数
grep wang /etc/passwd | wc –l //统计目录/etc下的passwd文件中有多少个用户名为wang的用户
四、文件归档及压缩命令
(一)文件归档命令
用户在处理文件过程中,有时需要对某些目录及文件进行打包备份的操作,或有时需要将几个文件组合成一个文件以便于网络传送,就像减肥瘦身了的五、六个美女挤坐一辆出租车一样,这时Unix系统提供的tar命令就能有用武之地了。使用tar 命令,可以将多个文件或目录合并成为一个tar包以便于存储及传输。tar命令的常用格式是:
tar cvf filename.tar file1 file2 …directory1 directory2 …
此处参数中c表示创建一个新的归档,v表示启动显示模式,tar会显示出所处理的每个文件名,f filename.tar表示使用指定的文件名作为归档文件。
如:要将/home/zcl/down目录中的文件全部归档为down.tar,可以使用如下命令
tar cvf down..tar /home/zcl/down
当用户想把已归档的文件复原,则可使用如下的命令格式:
当用户想把已归档的文件复原,则可使用如下的命令格式:
tar xvf filename.tar
(二)文件压缩命令
为了避免文件占用太多的磁盘空间,用户会选择将文件压缩存放。通常压缩会和归档组合使用,使用户能够对整个目录以及目录中的文件同时进行压缩。对许多 Windows用户来说,使用Winzip、Winrar等工具软件来压缩或解压文件是很平常的事,那么如何在Unix系统中对文件进行压缩与解压呢?下面介绍Unix系统中常用的三种压缩类型以及解压缩命令。
1、使用gzip/gunzip 命令解压缩文件
使用gzip命令压缩后的文件名称为“原文件名.gz”,它对应的解压命令是gunzip。命令格式如下:
gzip filename
gunzip filename.gz
如:要largefile.tar文件压缩成为largefile.tar.gz,则可以使用如下命令
gzip largefile.tar
如果要把largefile.tar.gz解压,则只需使用命令gunzip largefile.tar.gz即可。
2、使用compress/ uncompress命令解压缩文件
凡是经过compress命令压缩处理的文件,会在文件名后附加上“.Z”,它对应的解压命令是uncompress。命令格式如下:
compress filename
uncompress filename.Z
uncompress filename.Z
3、使用pack/unpack命令解压缩文件
凡是经过pack命令压缩处理的文件,会在文件名后附加上“.z”,它对应的解压命令是unpack。命令格式如下:
pack –f filename
unpack filename.z
unpack filename.z
五、进程管理与控制命令
“进程”顾名思义就是“正在进行着的程序”,在Unix系统中一个进程可视为一项正在执行的任务,这样一个命令也就是一个进程了。Unix系统具有检查和控制进程的相关命令,它们常被用于管理Unix系统。事实上,进程不仅包括用户所执行的命令,也包括了维持Unix系统正常运行的所有程序,且每一进程都有其唯一的代号,即进程标识符。
要想查看系统当前正在运行的进程信息,可使用命令:
ps [-options] //无参数时只显示当前用户在当前窗口中所运行的进程
//如果系统提示ps为非法命令,则在csh中可使用/usr/bin/ps,
//bash中可使用/usr/ucb/ps来替代ps
参数
|
解释
|
-e
|
列出所有正在运行的进程
|
-f
|
长列表显示进程的细节信息,一般与e一起使用
|
-u 用户名
|
显示指定用户正在运行的进程
|
如:要求长列表显示所有与用户zcl相关的进程信息,命令如下:
ps –ef | grep zcl
此外,如果想要查看进程占用系统资源的情况,可使用如下的两个命令:
/usr/ucb/ps –auwx //查看进程占CPU、内存等系统资源的情况
prstat //时时刷新当前系统的进程信息,并按所占系统资源大小排列
在某种特殊情况下,用户可能会无法正常的结束某一进程,这时就需要使用命令kill来杀掉这一进程,不过要注意的是用户只能杀掉由其自身创建的进程。命令格式如下:
kill [-signal] process-id
或
pkill [-signal] process-name
kill就像一名狙击手,实施的是精确的“点杀”,kill会精确的杀掉指定进程号的进程,如:
kill 12345 //“点杀”进程号为12345的进程,进程号可利用ps命令查出
kill -9 12480 //-9代表强制杀掉进程,但不会清理该进程所占的资源
pkill就像一名机枪手,实施的是威力巨大的“群杀”,pkill会杀掉所有指定的进程名的进程。如:
pkill sleep //杀掉系统中所有名为sleep的进程
这里,我们再引入一个新的概念——作业。作业这一概念只有在需要对进程区分为前后台时方被使用,它等同于进程的概念。前台进程是指可以和用户直接进行人机交互的进程,它可以接收键盘输入并将结果显示在显示器上。缺省状态下用户启动的Unix程序都运行在前台。后台进程是指不直接和用户进行交互的进程,用户一般是感觉不到后台进程的运行。要让某一程序在后台运行,只需在命令行的最后加上“&”符号。在Unix系统中可以同时在前台和后台运行多个进程,通常情况下,一般把需要和用户交互的程序放在前台执行,而把不需要以交互方式执行的程序置于后台运行。
使用jobs命令可以查看当前系统中正在执行的作业,如下图所示:
![](http://www.donews.net/images/blog_csdn_net/dev2dev/jobs.jpg)
在图中,“[]”中的数字代表作业号,此作业号可以配合作业管理命令一起使用:
fg %n
|
将某一作业放入前台运行(n代表作业号,下同)
|
bg %n
|
将某一作业放入后台运行
|
stop %n
|
挂起后台某一作业
|
kill %n
|
终止某一指定的作业
|
此外,还应掌握三个常用的键盘指令:
Ctrl + z
|
挂起前台正在运行的作业
|
Ctrl + d
|
正常的结束前台作业,即先执行完该进程后结束
|
Ctrl + c
|
终止前台作业(非正常方式)
|
如:
[例1] 要求后台运行find命令,在当前目录及其子目录下查找文件名前缀为file的文件。
解:通常当在后台运行命令时,最好将其运行结果输出重定向到一个文件中,以便日后检查或校对。因此,此题可以使用如下的命令:
find . -name “file*” >myfind &
这样,我们就可以通过查看myfind文件来查看查找结果了。在运行此命令的同时,我们还可以继续输入其它命令来进行其它操作。
[例2] 要求前台运行find命令,在当前目录及其子目录下查找文件名前缀为file的文件,运行过程中挂起进程,并将其放入后台运行。
解:此题可以使用如下的命令:
find . -name “file*” >myfind
^z (按Ctrl + z)
jobs //通过jobs命令来查看find进程的作业号,假设为1
bg %1
这里再补充与记取一个小知识点,即当在前台杀掉某一进程后,那么此进程的所有子进程都会同时被杀掉;而如果是在后台杀掉某一进程,那么此进程的所有子进程都将“过继”给“祖宗”进程(即进程号为1的进程)而继续运行。