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

linuxja 2017-04-25

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

《Linux探索之旅》全系列

内容简介


  1. 第二部分第九课:查找文件,无所遁形
  2. 第二部分第十课预告:第二部分测试题

查找文件,无所遁形


上一课 Linux探索之旅 | 第二部分第八课:RTFM 阅读那该死的手册,我们学习了很重要的技能:如何阅读使用手册。

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

之前的课程Linux探索之旅 | 第二部分第三课:文件和目录,组织不会亏待你中,我们已经见识过,Linux下文件的组织形式是很特别的,跟Windows不一样。

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

ls /

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

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

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

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

一起来学习吧。

locate命令,快速查找


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

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

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

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

locate renamed_file

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

 

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

我们再来用locate查找france文件(France是“法国”的意思。):

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

 

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

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

文件的数据库


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

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

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

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

 

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

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

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

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

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

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

因此我们可以这样:

sudo updatedb

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

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

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

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

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

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

find命令,深入查找


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

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

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

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


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

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

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

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

 

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

find命令的功能


find命令的用法是这样的:

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

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

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

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

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

find命令的基础用法


根据文件名查找

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

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

find -name "france1.jpg"

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

 

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

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

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

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

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

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

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

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

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

find /var/log -name "syslog"

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

 

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

Permission denied

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

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

sudo su

find /var/log "syslog"

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

 

可以看到,切换成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*"

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

 

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

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

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

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

find / -name "syslog"

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

根据文件大小查找


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

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

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

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

find /var -size +10M

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

 

这次,我们使用了-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

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

 

-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

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

 

可以看到只查找到了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"

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

 

我们在-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加回车表示对此文件不进行此操作。

总结


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

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

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

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

第二部分测试题预告


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

下一课:Linux探索之旅 | 第二部分测试题

相关推荐