您的位置:首页 > 运维架构 > Linux

【Linux探索之旅】第二部分第九课:查找文件,无所遁形

2015-09-04 05:49 597 查看


内容简介

1、第二部分第九课:[b]查找文件,无所遁形[/b]

2、第二部分测试题

查找文件,无所遁形

这一课不难,但挺重要的。

之前的课程我们见识过了Linux下文件的组织形式是很特别的,跟Windows不一样。

我们也用ls / 这个命令来列出根目录下的所有目录,有/bin,/etc,/var,/home,等等。而这些目录下又有子目录和文件,错综复杂。

这些目录中有一部分是历史遗留的,从Unix时代就有了。问题是:我们如何在这“茫茫文海”中查找我们需要的文件。

“人潮人海中,有你有我。相遇相识,相互琢磨”(黑豹乐队的《无地自容》),小编你可以了...

不要担心,这一课我们就来学习Linux中用于文件查找的工具。

有的工具查找起来快,但是不全面;有的比较慢,但是全面。

一起来学习吧。

locate命令,快速查找

第一种查找文件的方法可以说是很简单的。用到的命令是locate。

locate是英语“定位”的意思。这个命令用于定位要查找的文件,而且此命令很快。

locate命令的用法也很直观,后接需要查找的文件名(当然也可以用正则表达式)。

例如我们来查找一个叫做 renamed_file的文件:

locate renamed_file




可以看到locate命令帮我们找到了renamed_file文件,位于 /home/oscar/linux_c目录下。

我们再来用locate查找france文件:



我们运行locate france后,终端列出了所有包含france的文件和目录。

所以locate命令是搜索包含关键字的所有文件和目录。

文件的数据库

在使用locate命令查找文件时,大家可能会遇到这样的问题:我刚创建的文件,为什么用locate命令查找不到呢?

这正好是locate命令的缺陷,我正要说到:locate命令不会对你实际的整个硬盘进行查找,而是在文件的数据库里查找记录。

locate命令的原理如下图所示:



对于刚创建不久的文件,因为它们还没被收录进文件数据库,因此locate命令就找不到其索引,自然就不会返回任何结果。

Linux系统一般每天会更新一次文件数据库。因此,只要你隔24小时再用locate查找,应该就能找到你刚创建的文件了。

但是你会说:“臣妾不想等这么久啊。难道哀家要在这深宫之中等候多时么?”

当然不是,甄嬛不会一直赢的,皇后总有出头之日。

我们可以用updatedb命令强制系统立即更新文件数据库。但是updatedb命令只能由root用户执行。

update是英语“更新”的意思;db是英语database的缩写,表示“数据库”。所以连起来就是“更新数据库”。

因此我们可以这样:

sudo updatedb


这个命令执行会需要一点时间,小编执行的时候大概等了几分钟才完毕。

一旦执行成功,你再用locate查找你刚才创建的文件,就可以找到了。

总结一下:locate命令方便快捷,易于使用。但缺点也很明显:

locate命令会列出所有在文件数据库中找到的内容,有时候结果太多了,太繁杂。

locate命令不能找到一天之内刚创建的文件,除非你先用root身份运行updatedb命令来更新文件数据库。

当locate命令不够用时,我们需要一个更强大的命令,它就是find命令。

find命令,深入查找

find是英语“找到”的意思,find命令也用于查找文件。

find命令是查找文件的利器,而且它可以让我们对每个找到的文件做后续的操作。find命令非常强大,可以做很多事情,但是也因此比较复杂。

find命令可以说是Linux中最常用的命令之一了。所以,一起来探秘吧。

find命令查找当前实际的文件

与locate命令不同,find命令不会在文件数据库中查找文件的记录,而是遍历你的实际硬盘。

所以,如果你的硬盘容量很大的话,那find命令会查找比较久。

find命令的原理如下图所示:



find命令的这种耿直的查找方式保证了我们不会遗漏一天之内创建的文件。但这绝对不是find的唯一强大之处,远远不是。

find命令的功能

find命令的用法是这样的:

find 《何处》《何物》《做什么》

这几个参数中,只有《何物》是必须指定的,也就是要查找什么。

何处:指定在哪个目录中查找。此目录的所有子目录也会被查找。与locate命令的查找所有文件数据库的所有记录不同,find命令可以限定查找目录,比如我们可以只让find查找/home目录。默认地,假如我们没有给出《何处》这个参数,那么find命令会在当前目录及其子目录中查找。

何物:也就是要查找什么。我们可以根据文件的名字来查找,也可以根据其大小来查找,也可以根据其最近访问时间来查找,等等。这个参数是必须的。

做什么:用find命令找到我们要的文件后,可以对每个文件做一定的操作,称为“后续处理”。默认地,假如不指定这个参数,那么find命令只会显示找到的文件,不会做其他事情。

find命令的基础用法

根据文件名查找

我们首先来学习最基本的查找:用文件名来查找。

首先,我们定位到用户的家目录中(对于小编来说是/home/oscar),然后我要在当前目录及其子目录中查找france1.jpg这个文件。France是“法国”的意思。

find -name "france1.jpg"




这里,我们用-name参数指定了文件名字,是france1.jpg,用双引号括起来。不加双引号或者用单引号也是可以的。

name是英语“名字”的意思。

经过了一点时间,查找才停止,因为find命令会遍历指定的所有目录。

最终,find命令找到了france1.jpg这个文件,位于/home/oscar/Photos 目录下。

如果find命令没有结果显示,那么表示此文件不存在。

因为我们没有指定《何处》这个参数,所以find命令就会在当前目录(~,也就是用户的家目录中,/home/oscar)及其子目录中查找。

假如,现在我位于我的家目录中,我却想在其他目录中进行查找,怎么办呢?

那就须要指定《何处》这个参数了。

例如,我要在/var/log目录下查找名为syslog的文件,我应该这么输入:

find /var/log "syslog"




但是,作为普通用户的oscar,没有权限在var/log的子目录中查找。因此,显示:

Permission denied

permission是“许可”的意思,denied是“否决”的意思。就是说没有权限做这事。

我们可以切换成root身份,再来执行查找。

sudo su
find /var/log "syslog"




可以看到,切换成root后,就可以查找了。并且找到了两个结果:

/var/log/installer/syslog

/var/log/syslog

在上面的查找中,我们的参数如下:

何处:/var/log(及它的子目录)

何物:syslog

没有指定《做什么》参数,因此find命令默认显示了查找到的文件。

我们注意到了:与locate命令不同的是,find命令只会查找完全符合《何物》的字符串表示的文件。locate会查找所有包含关键字的文件。比如,如果要用find来找thing这个文件,那么只会找到名字就是thing的文件;而locate命令会查找到比如thing,thing1,onething,twothings这样的文件。

因此,我们用find查找syslog文件时,就不会查找到syslog2这样的文件。

不过我们可以用我们之前学过的通配符:*(星号)来实现匹配多个名称。

例如,我要查找所有以syslog这个关键字开头的文件,可以这样来实现:

find /var/log -name "syslog*"




可以看到,在syslog之后加了*之后,就会匹配凡是以syslog开头的文件了,因为*号是匹配一个或多个任意字符。

那聪明如你肯定想到了,如果要查找以syslog结尾的文件,可以用:*syslog

那你肯定也知道,如何查找包含syslog这个关键字的文件,可以用 *syslog*

那如果我要在整个硬盘里查找怎么做呢?很简单:

find / -name "syslog"


在Linux的根目录查找很花时间,而且,如果你不是以root身份查找的话,就会有很多目录提示你“无权限访问”。

根据文件大小查找

如果你不知道你要找的文件的名称,那怎么办呢?

不要担心,还有其他方式来查找文件的。

我们先来看如何根据文件大小查找。

例如,我们可以查找/var中大小超过10M的文件(当然你要以root身份):

find /var -size +10M




这次,我们使用了-size参数,来指定查找文件的大小。size是英语“尺寸,大小”的意思。

后面紧跟的+10M表示大于10兆字节。M是兆,也就是10的6次方;平时我们所说的多少个Ko,Mo,Go其实分别是千字节,兆字节,千兆字节,一个字节是8位二进制数。我们说硬盘512G,就是硬盘容量有512千兆字节(虽然实际容量是不到的,不深究)。

如果我们要查找小于指定大小的文件,可以用减号。例如:

find /var -size -50K


表示查找小于50Ko的文件。

find /var -size +20G


表示查找大于20Go的文件。

如果没有加减号,则查找大小等于指定数值的文件。

根据文件的最近访问时间查找

如果你记得你近7天里在家目录中访问过JPG格式的图片,但是你忘记它们的名字了,如何查找呢?

可以使用-atime参数。atime是access和time的缩写,access是英语“访问,进入”的意思,time是英语“时间”的意思。

可以这样查找:



find -name "*.jpg" -atime -7




-atime参数后面紧跟的-7表示7天之内,减号的作用是表示小于。

仅查找目录或文件

我们可以指定查找的文件类型,我们知道Linux中文件的类型大致分为两种:目录和文件。

因此,我们可以用-type参数来指定查找的文件类型。type是英语“类型”的意思。

-type d:只查找目录类型。d是directory的首字母,表示“目录”。

-type f:只查找文件类型。f是file的首字母,表示“文件”。

如果不用-type参数指定类型,那么find命令默认是查找目录和文件的。比如说,有syslog这个文件,和syslog这个目录,那么find会把他们都查找出来。

用法如下:

find /var/log -name "mysql" -type d




可以看到只查找到了mysql这个目录。

find命令的高级用法:操作查找结果

到目前为止,我们只是使用了find的基本功能。我们并没有指定《做什么》这个参数,也就是还没对查找到的结果做任何操作。

当然了,默认地,find命令会显示每个查找到的文件。

事实上,

find -name "*.jpg"


等价于

find -name "*.jpg" -print


-print参数用于打印结果。print是英语“打印”的意思。

格式化打印查找结果



默认地,find命令只列出查找到的文件,但是我们可以将其用格式化的方式打印出来。

我们可以使用-printf参数。是不是想起了C语言中的printf函数?是的,printf是print formatted的缩写,表示“格式化打印”。

例如,我们可以这样打印查找到的内容:

find ~/Photos -name "*.jpg" -printf "%p - %u\n"




我们在-printf参数后面写了"%p - %u\n",这个格式字符串的意思如下:

%p:文件名。

-:就是一个短横。

%u:文件的所有者,这里是小编的用户名,所以是oscar。

\n:用于换行。

可以看到,用法和C语言的printf函数很类似。

删除查找到的文件

假如我要删除查找到的文件,我可以用-delete参数。用法很简单:

find -name "*.jpg" -delete


将会删除当前目录及其子目录下所有以.jpg为后缀的文件。而且不会有确认提示。所以慎用-delete参数。

调用命令

使用-exec参数,可以后接一个命令,对每个查找到的文件进行操作。

exec是execute的缩写,是英语“执行”的意思。

假设我想要将当前目录下所有查找到的JPG文件的访问权限都改为600,那么我们可以这样做:

find -name "*.jpg" -exec chmod 600 {} \;


就是说对于每个找到的.jpg结尾的文件,都进行-exec参数指定的操作:

这个操作不必用双引号括起来。

{} 会用查找到的每个文件来替换。

\; 是必须的结尾。

虽然-exec参数一开始有点看不懂其用法,但是慢慢地你会发现,这个参数太强大了,你可以对查找到的文件做任何你想要的操作。

如果你对于没有确认提示不太放心,你可以将-exec参数换成-ok参数,用法一样,只不过-ok参数会对每一个查找到的文件都做确认提示,输入y加回车表示对此文件进行此操作;输入n加回车表示对此文件不进行此操作。

总结

为了在Linux硬盘中查找一个文件,我们可以用locate命令。这个命令很快,因为它不会实际遍历硬盘,而是在被称为文件数据库的记录里查找,所以它找不到刚添加的文件。为了更新文件数据库,我们可以用root用户身份运行updatedb命令。

find命令比locate命令更强大,用法更多样。它会遍历实际的硬盘来查找文件,所以更慢,但是更精确。find命令可以跟三个参数:《何处》,《何物》,《做什么》。

可以根据文件的名字来查找,用-name参数;根据大小来查找,用-size参数;根据最后访问时间来查找,用-atime参数。等等。

查找到了文件,我们也可以选择不显示,而是删除文件,用-delete参数,或者对文件执行命令,用-exec参数。

第二部分测试题预告

今天的课就到这里,一起加油吧!

下一课:第二部分测试题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: