第五章 搜索文件和文本
翻译:hfzheng
电子邮件:hfzheng@sohu.com
转载请保留此信息!
使用find命令定位文件
使用find命令可以定位目录树中的文件,使用该命令可以基于指定的规则来定位文件,例如指定文件名称、大小、所有者、修改时间、类型。
find命令递归搜索路径列表中的目录树查找满足指定规则的文件。当那些满足条件的文件定位后,在屏幕上将显示每个文件的路径。
命令格式
find pathnames expressions actions
命令行中的第一个参数为搜索开始的路径名称,可以使用绝对路径或者相对路径方式指定。其他参数指定搜索规则以及一旦搜索到文件到所要采取的动作。以下三个部分分别说明了可以使用在find命令中的参数、表达式和动作。
参数定义
pathname搜索开始的目录路径
expression一个或者多个选项指定的搜索规则,指定多个搜索规则,find命令将执行and操作,也就是说,所有列出的搜索规则都必须满足。
Find命令中可以使用的expressions
-name filename搜索匹配指定文件名的文件,元字符如果放在引号里面也可以使用
-size [+|-]n搜索文件大小大于(+n)或者小于(-n)的文件,n代表512字节块
-atime [+|-]n搜索访问时间超过(+n)或者不足(-n)天的文件
-mtime [+|-]n搜索修改时间超过(+n)或者不足(-n)天的文件
-user loginID搜索属于loginID名称所有的文件
-type指定搜索的文件类型,如d目录,f文件
-perm搜索具有指定访问许可的文件
-print指示find打印当前路径到终端屏幕,这是默认设置
find命令中可以使用的动作
-exec command {} \;自动对每个找到的文件执行指定的命令,必须包含字符串{} \;用来告诉find命令对于每个由搜索规则指定的文件执行命令,在\之前必须要一个空格;
-ok command {} \;exec的交互方式,对find命令的结果执行命令时要求输入确认;
下面举例说明find命令的功能:
$ find / -name core
$ find ~ -name core -exec rm {} \;
$ find . –mtime +90
$ find ~ -size +57
$ find /usr –name ‘*tif'
比较文件之间的差异
使用cmp命令比较文本之间的差异
使用cmp命令轻松确定可以文本之间的差异。只有当文本文件不同时cmp命令才打印结果,没有任何结果显示,表明文件完全相同。
cmp命令对每个文件一个字节一个字节比较,如果文件之间有不同,cmp命令打印出文件之间不同的字节数和行数,然后停在第一个不同行上。该命令可以比较二进制文件和ASCII文件。
命令格式
cmp filename1 filename2
$ cmp fruit fruit2
fruit fruit2 differ: char 27, line 5
输出说明了两个文件第一次出现不同的位置,在上面的示例中在第5行的第27个字符。
使用diff命令比较文本之间的差异
diff是另外一个用于比较文本之间差异的命令。该命令的结果是一行一行显示两个文本文件之间的不同,为你编辑一个文件以使得该文件和另外一个文件相同提供指导。
命令格式
diff –option filename1 filename2
下面列出可以在diff中使用的选项:
-i忽略大小写,例如A等于a
-c产生差异列表。结果以文件名称和创建日期开始,接下来就是一组星号,接着显示file1文件的行数,file1中的实际行,与file2不同的行前面有(-)标签。接下来就 是file2文件的行数,file2中的实际行,与file1不同的行前面有(+)标签。
使用带-c选项的diff命令
当使用带-c选项的diff命令时,结果分三个部分显示。
第一部分显示要比较的文件名称、创建日期,然后跟一串星号
第二部分为file1文件的显示,显示file1文件的行数,file1中的实际行,与file2不同的行前面有(-)标签。
第三部分为file2文件的显示,显示file2文件的行数,file2中的实际行,与file1不同的行前面有(+)标签。
例如,执行下面的命令使用diff来比较文件:
$ cat fruit
lemon
orange
apple
banana
pear
mango
tomato
pomegranate
$ cat fruit2
lemon
orange
apple
banana
tomato
guava
mango
pomegranate
$ diff -c fruit fruit2
*** fruit Wed Jan 12 15:50:36 2000
--- fruit2 Wed Jan 12 15:51:04 2000
***************
*** 2,8 ****
orange
apple
banana
- pear
- mango
tomato
pomegranate
--- 2,8 ----
orange
apple
banana
tomato
+ guava
+ mango
pomegranate
$
数据排序
sort命令排列文本行,并把文件打印输出到屏幕上。Sort命令提供了一种以字母或者数字顺序快速组织数据的方法。默认方式下,sort命令使用white space来分割文件中的不同域。
命令格式
sort –options filenames
选项
可用的选项包括定义排序的类型、从哪个域开始排序。
-n 以数字方式排序
(+|-)n以n个分隔符开始(+n)、结束(-n)的域排序
-r反向排序
-f忽略大小写
+nM排列域的前三个字符作为缩写的月份名称
-d排列目录顺序,只考虑字母、数字和空格。其他字符忽略
-o filename输出结果到指定filename文件中
-b在限定起始和结束排序域时忽略开头的空格字符
-t char使用char字符作为域分隔符,如果没有指定该参数,则使用空格字符作为默认参数
使用带不同选项的sort命令
下面的示例显示了如何使用带不同选项的sort命令:
$ cat fileA
Annette 48486
Jamie 48481
Fred 48487
Sondra 48483
Janet 48482
$
$ sort fileA
Annette 48486
Fred 48487
Jamie 48481
Janet 48482
Sondra 48483
$ sort +1n fileA
Jamie 48481
Janet 48482
Sondra 48483
Annette 48486
Fred 48487
第一条命令使用cat命令来显示文件的内容,第一条sort命令按字母排序,从每行的第一个字符开始。
第二条sort命令对第二个域按数字排序(使用+1语法跳过一个分隔符)。
在一个文件中的不同域使用sort命令
下面的示例描述了如何在一个文件中的不同域上使用sort命令:
$ ls -ld f* > list
$ cat list
-rw-r--r-- 1 user1 staff 218 Mar 1 11:36 feathers
-rw-r--r-- 1 user1 staff 218 Mar 1 11:36 feathers_6
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.1
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.2
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.3
-rw-r--r-- 1 user1 staff 1696 Feb 22 14:51 file1
-rw-r--r-- 1 user1 staff 156 Mar 1 14:48 file2
-rw-r--r-- 1 user1 staff 218 Feb 22 14:51 file3
-rw-r--r-- 1 user1 staff 137 Feb 22 14:51 file4
-rw-r--r-- 1 user1 staff 56 Feb 22 14:51 fruit
-rw-r--r-- 1 user1 staff 57 Feb 22 14:51 fruit2
$ sort -rn +4 list -o num.list
$ cat num.list
-rw-r--r-- 1 user1 staff 1696 Feb 22 14:51 file1
-rw-r--r-- 1 user1 staff 218 Mar 1 11:36 feathers_6
-rw-r--r-- 1 user1 staff 218 Mar 1 11:36 feathers
-rw-r--r-- 1 user1 staff 218 Feb 22 14:51 file3
-rw-r--r-- 1 user1 staff 156 Mar 1 14:48 file2
-rw-r--r-- 1 user1 staff 137 Feb 22 14:51 file4
-rw-r--r-- 1 user1 staff 57 Feb 22 14:51 fruit2
-rw-r--r-- 1 user1 staff 56 Feb 22 14:51 fruit
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.3
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.2
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.1
$ sort +5M +6n list -o update.list
$ cat update.list
-rw-r--r-- 1 user1 staff 56 Feb 22 14:51 fruit
-rw-r--r-- 1 user1 staff 57 Feb 22 14:51 fruit2
-rw-r--r-- 1 user1 staff 137 Feb 22 14:51 file4
-rw-r--r-- 1 user1 staff 218 Feb 22 14:51 file3
-rw-r--r-- 1 user1 staff 1696 Feb 22 14:51 file1
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.1
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.2
-rw-r--r-- 1 user1 staff 0 Feb 25 12:54 file.3
-rw-r--r-- 1 user1 staff 156 Mar 1 14:48 file2
-rw-r--r-- 1 user1 staff 218 Mar 1 11:36 feathers
-rw-r--r-- 1 user1 staff 218 Mar 1 11:36 feathers_6
$
第一个示例把ls命令的输出保存在文件list中,然后使用cat命令来查看文件内容。
第一条sort命令对第五个域产生一个反向、数字排序,排序的结果保存到文件num.list中。
第二条sort命令对文件list的域6和7进行多层排序,选项+5M对第6个域月份项按字母顺序排序,+6n对第7域天按数字顺序进行第二层排序,所有的排序结果保存在update.list文件中。
搜索文件中的文本
Solaris操作环境提供了一系列命令用于在一个或者多个文件中搜索特定的字符模式。模式可以是一个单字符、字符串、单词或者句子。
由定义,用于匹配一个搜索中的相同字符的字符模式称为正则表达式。用于搜索正则表达式的命令称为grep、egrep和fgrep。
Grep命令用于在一个文件中搜索正则表达式,把所有包含正则表达式的行送标准输出。
Egrep和fgrep命令是grep命令的变体,称为扩展grep和快速grep。
使用grep命令
grep命令用于在一个或者多个文件中搜索字符模式或者正则表达式,把每一行包含有指定字符模式的行输出到屏幕,但这并不改变文件内容。
命令格式
grep –options pattern filenames
选项
-i忽略大小写,大写字母和小写字母认为是相同的
-l只是列出带匹配行的文件名称
-n在每一行之前加上行号
-v列出所有不匹配的行
-c只是列出包含pattern的行数
正则表达式中的元字符
grep命令支持几个元字符用来进一步定义搜索模式。下面列出常用的几个基本的元字符
^行开始标识符‘^pattern'匹配所有以pattern开头的行
$行结束标识符‘pattern$'匹配所有以pattern结束的行
.匹配一个字符‘p…..n'匹配所有包含有以p开头后跟五个字符,紧接着跟一个字符的行
*[a-z]*匹配小写字符
[]匹配模式中的单个字符‘[pP]attern'匹配包括pattern和Pattern模式的行
[^]匹配不在模式中单个字符‘[a^m]attern'匹配以a到m结尾attern的所有行
使用grep命令搜索正则表达式的示例
下面的示例使用grep命令来搜索正则表达式,要搜索文件/etc/group中的所有包含有模式root的行,执行下面的命令:
$ grep -n root /etc/group
1:root::0:root
3:bin::2:root,bin,daemon
4:sys::3:root,bin,sys,adm
5:adm::4:root,adm,daemon
6:uucp::5:root,uucp
7:mail::6:root
8:tty::7:root,tty,adm
9:lp::8:root,lp,adm
10:nuucp::9:root,nuucp
12:daemon::12:root,daemon
$
要搜索文件/etc/group中的所有不包含有模式root的行,执行下面的命令:
$ grep -v root /etc/group
other::1:
staff::10:
nobody::60001:
noaccess::60002:
sun4prog::100:
funda::105:
cprg::170:
csh::180:
sysadmin::14:
fire::20:
sl300::30:
java::190:
cplus::700:
sysint::1000:
internals::2000:
sunnetmgr::3000:
OpenWindows::5000:
SAE::5500:
guest::20000:guest,kbrown
$
只是搜索文件名称中包含模式root,执行如下命令:
$ cd /etc
$ grep -l root group passwd hosts
group
passwd
$
需要在目录/etc中的所有文件中搜索模式the,只是列出匹配模式the和The的文件名称,执行下面示例:
$ cd /etc
$ grep -li the *
$ cd /etc
$ grep -li the *
aliases
asppp.cf
dacf.conf
device.tab
devlink.tab
dgroup.tab
fmthard
format
<output omitted>
syslog.conf
system
termcap
TIMEZONE
ttysrch
umountall
grep: can't open utmppipe
$
需要在文件/etc/group中搜索模式root,并且只打印包含该模式的行数,执行下面的命令:
$ grep -c root group
10
$
需要在ls –la命令的输出中搜索模式mar 1,执行下面的命令:
$ ls -la | grep -i 'mar 1'
$
$ ls -la | grep -i 'mar 1'
prw------- 1 root root 0 Mar 1 11:05 initpipe
-r--r--r-- 1 root root 806 Mar 1 13:39 mnttab
prw------- 1 root root 0 Mar 1 11:06 utmppipe
$
egrep命令
egrep命令用于在一个或者多个文件中搜索字符模式或者正则表达式,正则表达式支持扩展元字符。Egrep命令使用与grep命令完全相同的选项。
命令格式
egrep –options pattern filenames
扩展正则表达式元字符
+匹配一个或多个开头字符‘[a-z]+ark'匹配一个或多个小写字母后跟ark
x|y匹配x或者y‘apple|orange'匹配任何一个表达式
()组字符‘search(es|ing)+'匹配一次或者多次出现
使用fgrep命令
fgrep命令搜索文件中的指定模式,与grep和egrep不同之处在于不能识别指定在命令行中任何正则表达式元字符。它只是识别字母的字面意思,?作为问号处理,$作为美元符号处理。