在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表示文件更改的当天可以看下图,更好的帮助大家来理解 mtime atime ctime 如将系统上面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系统了。今天的内容,重在实践,通过实践加深理解,在实践中解决问题。