一天一点学习Linux之文件查找/搜索

来源:岁月联盟 编辑:exp 时间:2011-10-23

 

在Linux文件系统中,搜索概念有两种,一种是搜索文件名,另一种是在一个文件中搜索指定的内容。文件的查找,在操作系统的使用中,是一个非常重要的功能,所以,今天我们就来学习研究他了。

 

一、文件的搜索

(一)命令的查找

 

我们在前面的内容中,讲到PATH变量,这里面写了一些命令的所在位置,而且我们常用的TAB键补全功能,也会在这些目录里面来查找相关的命令。但某个命令具体在哪个位置,我们可能还不知道,如果想找到他的具体位置的话,那么可以通过查找来发现他。

 

查找命令文件which

此命令会在环境变量PATH设置的目录里面查找内容。

这里面有个-a参数,他将所有从PATH变量的目录中找到的命令全部列出,而不只列出第一个被找到的命令名称。

在RHEL6系统中,你可以随便cp一个命令到用户的家目录的bin(自己建立)目录里面,然后用which和which -a来查找一下看看,你就会明白-a参数的意义了。

注:which后面跟的是要查找的命令全名,不能用通配符。

如果你想用which来查找cd命令,你会发现找不到cd命令,

[root@yufei ~]# which cd

/usr/bin/which: no cd in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)

这是为什么呢?系统中不存在这个命令,为什么我能使用此命令呢?其实这个cd命令不是放在系统的PATH中的,而是集成在shell中了。当然找不到,不过,你也可以通过type命令来查看

[root@yufei ~]# type cd

cd is a shell builtin

这个type也是shell中的命令

type命令其实不能算查找命令,它是用来区分某个命令到底是由shell自带的,还是由shell外部的独立二进制文件提供的。如果一个命令是外部命令,那么使用-p参数,会显示该命令的路径,相当于which命令。

 

(二)普通文件的查找

在Linux系统上的文件查找命令find,绝对不亚于windows系统上的查找,但find不足的地方就是速度比较慢,而且要大量读取硬盘内容。其实,在平时使用的时候,我们常用的命令并不是find,而是whereis或locate,因为他们是通过查找数据库里面的数据来查找文件的,这速度就会变的很快了,但这两个文件不一定能找到我们想要的内容,特别是一些新建议的文件,因为数据库还没有储存相应的信息。怎么办,没有关系,这个数据库除了定时更新外,我们还可以手动对其更新(updatedb)。好了,下面我们就来具体看看他们三个命令的用法。

 

whereis会在数据库中查找二进制,源代码文件和帮助手册文件

 

-s  只查找原始代码文件。

-S<目录>  只在设置的目录下查找原始代码文件。

-b  只查找二进制文件。

-B<目录>  只在设置的目录下查找二进制文件。

-m  只查找说明文件。

-M<目录>  只在设置的目录下查找说明文件。

如果省略参数,则返回所有信息。

 

locate也是在数据库中查找文件,不限制是什么文件

 

-i 忽略大小写

如果这个命令后面跟上文件名(字符)的话,那么这个命令执行的时候,会把系统中所有包含此字符的文件全部列出来。这个后面的名字就相当于关键字一样。

[root@yufei ~]# locate log

会列出很多内容出来

这个命令可以使用通配符,但在使用的时候要用”/”来处理一下,否则就查询当前的目录了

[root@yufei ~]# pwd

/root

[root@yufei ~]# locate *.log

/root/install.log

/root/install.log.bak

/root/install.log.syslog

/root/Desktop/install.log

/root/Desktop/install.log.syslog

上面的命令把当前目录(/root)里面所有包涵.log的文件全部找出来,无论是不是以.log结尾

[root@yufei ~]# locate /*.log

这个显示的内容比较多,他把系统中所有以.log结尾的文件全部找出来了。

虽然只是多了一个反斜杠,结果确明显不同

如果说,你要用”?”这个通配符,那么就要用-b这个参数了。当然上面的也可以用-b参数

[root@yufei ~]# locate -b /????.log

/var/log/boot.log

/var/spool/plymouth/boot.log

为了方便大家的记忆,建议大家在使用通配符号的时候,统一用-b这个参数。而且可以把反斜杠换成”””

locate -b ‘????.log’

locate -b ‘*.log’

这样可以和后面的find命令统一起来,省得大家搞混淆了。

更多的关于单引号与双引号的区别,请参考shell中单引号、双引号、反引号、反斜杠的使用

以上两个命令都是通过/var/lib/mlocate/mlocate.db这个数据库来查询内容的,所以,为了得到更准确的查找结果的话,在每次命令以上两个命令的时候,先执行updatedb命令,这样就不会把刚刚删除的文件再找出来,也不会找不到刚刚新建的文件了。

 

find 是最常见和最强大的查找命令,你可以用它找到任何你想找的文件。

 

语法格式如下

find <指定目录> <指定条件> <指定动作>

 

一般的参数

 

-name filename 按照文件名查找文件

-size [+-]SIZE 找比SIZE还要大(+)或小(-)的文件。这个SIZE的格式有:

c: 代表byte,k: 代表1024bytes。

所以,要找比50KB还要大的文件,就是用-size +50k

-type 查找某一类型的文件(b、d、c、p、l等等文件类型)

-newer file :file为一个存在的档案,列出比file文件还要新的文件

-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找

-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略

 

权限相关的参数

 

-perm mode 查找权限为mode(数字表示的权限)的文件

-perm -mode 查找权限全部包括mode(数字表示的权限)的文件。找到的文件权限比参考权限(mode)要大

-perm +mode 查找包含任一mode(数字表示的权限)的文件.找到的文件权限比参考权限(mode)要小

 

用户和组相关的参数

 

-user username :按照文件所有者来查找文件

-uid n :按照文件所有者的UID来查找文件

-group groupname :按照文件所属的组来查找文件

-gid n :按照文件所属组的GID来查找文件

-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在

-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在

 

和时间相关的参数

 

共有-atime, -ctime 与-mtime ,以-mtime说明,其他两个也一样

-mtime n :n为数字,意义为在n天之前(n当天)被更动过内容的文件

-mtime +n :列出在n天之前(不含n天本身)被更动过内容的文件名

-mtime -n :列出在n天之内(含n天本身)被更动过内容的文件名

-n表示文件更改时间距现在n天以内

+n表示文件更改时间距现在n天以前

n表示文件更改的当天

可以看下图,更好的帮助大家来理解

 

如将系统上面24小时内有更动过内容(mtime)的文件列出

find / -mtime 0

那个0是重点,0代表目前的时间,所以,从现在开始到24 小时前。

 

后续的动作参数

 

-exec command :command为其他指令,-exec后面可再接额外的命令来处理查找到的结果。

exec选项后面的格式:所要执行的命令或脚本+一对”{}”+”一个空格”+一个”/”+一个分号”;”。

最后的样式:-exec command {} /;

注:

1、{} 代表的是由find找到的内容,结果会被放置到{}中

2、-exec一直到/;是关键词。代表find额外动作的开始(-exec)到结束(/;),在这中间的就是find指令内的额外动作

3、因为”;”在bash环境下是有特殊意义,因此利用反斜杠来转义

 

下面看几个例子

1、查找/etc目录下的所有文件,并用ls -l把他们列出来

[root@yufei ~]# find /etc/ -type f -exec ls -l {} /;

2、在/var/log/目录中查找更改时间在5日以前的文件并删除它们

[root@yufei ~]# find /var/log/ -type f -mtime +5 -exec rm {} /;

如果你要进行这项操作的话,为了安全,建议先用ls再用rm,如果你确认没有问题的话,当然完全没有问题,用什么命令都可以。当然,也有一个确认的功能,下面就来看看这个-ok

3、在/var/log/目录中查找所有以.log结尾的文件名、更改时间在5日以上的,并删除它们,但在删除之前先给出提示。

[root@yufei ~]# find /var/log/ -name ‘*.log’ -mtime +5 -ok rm {} /;

这时候,如果找到了符合的文件,就会给出删除提示,按y键删除文件,按n键不删除。

4、查找所有的passwd文件,看看在这些文件中是否存在一个某个用户

[root@yufei ~]# find /etc -name “passwd*” -exec grep “yufei” {} /;

5、找出/etc底下,文件大小介于50K 到60K 之间的文件,并将权限完整的列出

[root@yufei ~]# find /etc -size +50k -a -size -60k -exec ls -l {} /;

那个-a 是and的意思,为符合两者才符合

6、找出/etc 底下,容量大于1500K 以及容量等于0的文件

[root@yufei ~]# find /etc -size +1500k -o -size 0

相对于-a ,那个-o 就是或(or)的意思

 

xargs

 

在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是”参数列太长”或”参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

 

看几个例子

1、查找/tmp目录下,名字为core的文件,并将其删除

[root@yufei ~]# find /tmp -name core -type f -print | xargs /bin/rm -f

2、在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限

[root@yufei ~]# find . -perm -7 -print | xargs chmod o-w

3、用grep命令在所有的普通文件中搜索hostname这个词

[root@yufei ~]# find / -type f -print | xargs grep “hostname”

[root@yufei ~]# find / -name /* -type f -print | xargs grep “hostnames”

其实这两个命令是一样的意思。和前面我们讲的一样,反斜杠”/”用来取消find命令中的*在shell中的特殊含义。

 

通过上面的一些例子,find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。而且在find的帮助文件中也有相应的帮助说明。大家可以参考学习。

 

二、在文件中搜索关键词

grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

由于正则表达式我们还没有学习,在这里只做简单的介绍几个例子,来让大家了解一下grep。

1、在/etc/passwd中查找yufei用户的相关信息

[root@yufei ~]# grep yufei /etc/passwd

yufei:x:500:500:yufei:/home/yufei:/bin/bash

2、查看系统日志/var/log/message文件,并查找2月12号的日志内容

[root@yufei ~]# cat /var/log/messages |grep ‘Feb 12′|more

这个例子我们用到了管理符号,翻页命令

 

通过上面讲解,你会发现在Linux系统上的查找,不亚于图形界面的windows系统吧,是不是越来越喜欢Linux系统了。今天的内容,重在实践,通过实践加深理解,在实践中解决问题

摘自 羽飞的博客