第十五部分(查找文件)

2020-04-10

locate - 查找文件的简单方法

locate 程序会执行一次快速的路径名数据库搜索,并且输出每个与给定子字符串相匹配的路径名。

例如,我们想要找到所有名字以“zip”开头的程序。因为我们正在查找程序,可以假定包含程序的目录以 “bin/” 结尾。因此,我们试着以这种方式使用 locate 命令,来找到我们的文件:

[root@VM_0_7_centos dev]# locate bin/zip
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
/var/lib/docker/overlay2/d028963bd1d73b62e83e688e5f1a276954190b81c513f23c0faef73cbb1009a3/diff/usr/bin/zipdetails

locate 命令将会搜索它的路径名数据库,输出任一个包含字串“bin/zip”的路径名。

如果搜索要求没有这么简单,locate 可以结合其它工具,比如说 grep 命令,来设计更加有趣的搜索:

[root@VM_0_7_centos dev]# locate zip | grep bin
/usr/bin/bunzip2
/usr/bin/bzip2
/usr/bin/bzip2recover
/usr/bin/funzip
/usr/bin/gpg-zip
/usr/bin/gunzip
/usr/bin/gzip
/usr/bin/unzip
/usr/bin/unzipsfx
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
/usr/lib/firmware/qed/qed_init_values_zipped-8.10.10.0.bin
/usr/lib/firmware/qed/qed_init_values_zipped-8.10.5.0.bin
...

locate 数据库来自何方?
你可能注意到了,在一些发行版中,仅仅在系统安装之后,locate不能工作,但是如果你第二天再试一下,它就正常工作了。怎么回事呢?locate数据库由另一个叫做 updatedb 的程序创建。通常,这个程序作为一个定时任务(jobs)周期性运转;也就是说,一个任务在特定的时间间隔内被 cron 守护进程执行。大多数装有 locate的系统会每隔一天运行一回 updatedb程序。因为数据库不能被持续地更新,所以当使用 locate时,你会发现目前最新的文件不会出现。为了克服这个问题,通过更改为超级用户身份,在提示符下运行 updatedb命令,可以手动运行 updatedb
序。

find - 查找文件的复杂方式

locate 程序只能依据文件名来查找文件,而 find 程序能基于各种各样的属性搜索一个给定目录(以及它的子目录),来查找文件。

在它的最简单的使用方式中,find 命令接收一个或多个目录名来执行搜索。例如,输出我们的家目录的路径名列表(包括文件及目录)。

[me@linuxbox ~]$ find ~

在最活跃的用户帐号中,这将产生一张很大的列表。因为这张列表被发送到标准输出,我们可以把这个列表管道到其它的程序中。让我们使用 wc 程序来计算出文件的数量:

[me@linuxbox ~]$ find ~ | wc -l
47068

Tests

比如说我们想在我们的搜索中得到目录列表。我们可以添加以下测试条件:

[me@linuxbox ~]$ find ~ -type d | wc -l
1695

添加测试条件-type d 限制了只搜索目录。相反地,我们可以使用这个测试条件来限定搜索普通文件:

[me@linuxbox ~]$ find ~ -type f | wc -l
38737

这里是 find 命令支持的常见文件类型测试条件:
find文件类型
我们也可以通过加入一些额外的测试条件,根据文件大小和文件名来搜索:让我们查找所有文件名匹配通配符模式“*.JPG”和文件大小大于 1M 的普通文件:

[me@linuxbox ~]$ find ~ -type f -name "*.JPG" -size +1M | wc -l
840

在这个例子里面,我们加入了 -name 测试条件,后面跟通配符模式。注意,我们把它用双引号引起来,从而阻止 shell 展开路径名。紧接着,我们加入 -size 测试条件,后跟字符串“+1M”。开头的加号表明我们正在寻找文件大小大于指定数的文件。若字符串以减号开头,则意味着查找小于指定数的文件。若没有符号意味着“精确匹配这个数”。结尾字母“M”表明测量单位是兆字节。下面的字符可以被用来指定测量单位:
find大小单位
find 命令支持大量不同的测试条件。下表是列出了一些常见的测试条件。请注意,在需要数值参数的情况下,可以应用以上讨论的“+”和“-”符号表示法:

find测试条件

操作符

即使拥有了 find 命令提供的所有测试条件,我们还需要一个更好的方式来描述测试条件之间的逻辑关系。例如,如果我们需要确定是否一个目录中的所有的文件和子目录拥有安全权限,怎么办呢?我们可以查找权限不是 0600 的文件和权限不是 0700 的目录。幸运地是,find 命令提供了一种方法来结合测试条件,通过使用逻辑操作符来创建更复杂的逻辑关系。为了表达上述的测试条件,我们可以这样做:

[me@linuxbox ~]$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)


find命令的逻辑操作符
因为圆括号对于 shell 有特殊含义,我们必须转义它们,来阻止 shell 解释它们。在圆括号字符之前加上一个反斜杠字符来转义它们。

逻辑操作符还有另外一个特性要重点理解。比方说我们有两个由逻辑操作符分开的表达式:

expr1 -operator expr2

在所有情况下,总会执行表达式 expr1;然而操作符将决定是否执行表达式 expr2。这里列出了它是怎样工作的:
find AND/OR 逻辑
为什么这会发生呢?这样做是为了提高性能。以 -and 为例,我们知道如果表达式 expr1 的结果为假,表达式 expr1 -and expr2 不能为真,所以没有必要执行 expr2。同样地,如果我们有表达式 expr1 -or expr2,并且表达式 expr1 的结果为真,那么就没有必要执行 expr2,因为我们已经知道表达式 expr1 -or expr2 为真。好,这样会执行快一些。为什么这个很重要?它很重要是因为我们能依靠这种行为来控制怎样来执行操作。

预定义的操作

执行 find 命令得到结果列表很有用处,但是我们真正想要做的事情是操作列表中的某些条目。幸运地是,find 命令允许基于搜索结果来执行操作。有许多预定义的操作和几种方式来应用用户定义的操作。首先,让我们看一下几个预定义的操作:
几个预定义的 find 命令操作

用户定义的行为

除了预定义的行为之外,我们也可以调用任意的命令。传统方式是通过 -exec 行为。这个行为像这样工作:

-exec command {} ;

这里的 command 就是指一个命令的名字,{} 是当前路径名的符号表示,分号是必要的分隔符表明命令的结束。

这里是一个使用 -exec 行为的例子,其作用如之前讨论的 -delete 行为:

-exec rm '{}' ';'

因为花括号和分号对于 shell 有特殊含义,所以它们必须被引起来或被转义。
我们也可以交互式地执行一个用户定义的行为。通过使用 -ok 行为来代替 -exec,在执行每个指定的命令之前,会提示用户:

find ~ -type f -name 'foo*' -ok ls -l '{}' ';'
< ls ... /home/me/bin/foo > ? y
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/foo
< ls ... /home/me/foo.txt > ? y
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

在这个例子里面,我们搜索以字符串“foo”开头的文件名,并且对每个匹配的文件执行 ls -l 命令。使用 -ok 行为,会在 ls命令执行之前提示用户。

提高效率

-exec 行为被使用的时候,若每次找到一个匹配的文件,它会启动一个新的指定命令的实例。
我们可能更愿意把所有的搜索结果结合起来,再运行一个命令的实例。例如,与其像这样执行命令:

ls -l file1
ls -l file2

我们更喜欢这样执行命令:

ls -l file1 file2

这样就导致命令只被执行一次而不是多次。有两种方法可以这样做。传统方式是使用外命令 xargs,另一种方法是,使用 find 命令自己的一个新功能。我们先讨论第二种方法。
通过把末尾的分号改为加号,就激活了 find 命令的一个功能,把搜索结果结合为一个参数列表,然后用于所期望的命令的一次执行。再看一下之前的例子,这个例子中:

find ~ -type f -name 'foo*' -exec ls -l '{}' ';'
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

每次找到一个匹配的文件,就会执行一次 ls 命令。通过把命令改为:

find ~ -type f -name 'foo*' -exec ls -l '{}' +
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

虽然我们得到一样的结果,但是系统只需要执行一次 ls 命令。

xargs

这个 xargs 命令会执行一个有趣的函数。它从标准输入接受输入,并把输入转换为一个特定命令的参数列表。对于我们的例子,我们可以这样使用它:

find ~ -type f -name 'foo*' -print | xargs ls -l
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

这里我们看到 find 命令的输出被管道到 xargs 命令,之后,xargs 会为 ls 命令构建参数列表,然后执行 ls 命令。

选项

最后,我们有这些选项。这些选项被用来控制 find 命令的搜索范围。当构建 find 表达式的时候,它们可能被其它的测试条件和行为包含,这里有一个最常被使用的选项的列表:
find命令选项

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值