如何使用查找和定位在Linux上搜索文件
介绍
用户在第一次学习如何使用 Linux 时遇到的一个问题是如何找到他们正在寻找的文件。
本指南将介绍如何使用恰当命名的 find
命令。 这将帮助您使用各种过滤器和参数搜索系统上的文件。 它还将简要介绍 locate
命令,该命令可用于以不同方式搜索文件。
先决条件
要遵循本指南,您需要访问运行基于 Linux 的操作系统的计算机。 这可以是您使用 SSH 连接到的虚拟专用服务器,也可以是您的本地计算机。 请注意,本教程使用运行 Ubuntu 20.04 的 Linux 服务器进行了验证,但给出的示例应该适用于运行任何版本的任何 Linux 发行版的计算机。
如果您打算使用远程服务器来遵循本指南,我们建议您先完成我们的 初始服务器设置指南 。 这样做将为您设置一个安全的服务器环境——包括一个具有 sudo
权限的非 root 用户和一个配置了 UFW 的防火墙——您可以使用它来培养您的 Linux 技能。
或者,您可以使用此页面上嵌入的交互式终端来试验本教程中的示例命令。 单击以下 Launch an Interactive Terminal! 按钮以打开终端窗口并开始使用 Linux (Ubuntu) 环境。
启动交互式终端!
注意:为了说明 find
和 locate
命令的工作原理,本指南中的示例命令搜索存储在 /
或 下的文件]根目录。 因此,如果您以非 root 用户身份登录终端,某些示例命令的输出中可能包含 Permission denied
。
这是意料之中的,因为您正在搜索普通用户通常无权访问的目录中的文件。 但是,这些示例命令应该仍然有效,并且有助于理解这些程序是如何工作的。
按名称查找
搜索文件最明显的方法是通过文件名。
要使用 find
命令按名称查找文件,可以使用以下语法:
find -name "query"
这将区分大小写,这意味着搜索 query
与搜索 Query
不同。
要按名称查找文件但忽略查询的大小写,请使用 -iname
选项:
find -iname "query"
如果要查找所有不符合特定模式的文件,可以使用 -not
反转搜索:
find -not -name "query_to_avoid"
或者,您可以使用感叹号 (!
) 反转搜索,如下所示:
find \! -name "query_to_avoid"
请注意,如果您使用 !
,则必须使用反斜杠 (\
) 转义字符,以便 shell 在 find
起作用之前不会尝试解释它。
按类型查找
您可以使用 -type
参数指定要查找的文件类型。 它是这样工作的:
find -type type_descriptor query
以下是一些可用于指定文件类型的描述符:
f
:普通文件d
:目录l
:符号链接c
:字符设备b
:块设备
例如,如果您想查找系统上的所有字符设备,您可以发出以下命令:
find /dev -type c
该命令专门只搜索 /dev
目录中的设备,该目录通常是在 Linux 系统中挂载设备文件的目录:
Output/dev/vcsa5 /dev/vcsu5 /dev/vcs5 /dev/vcsa4 /dev/vcsu4 /dev/vcs4 /dev/vcsa3 /dev/vcsu3 /dev/vcs3 /dev/vcsa2 /dev/vcsu2 /dev/vcs2 . . .
您可以使用如下命令搜索所有以 .conf
结尾的文件。 此示例在 /usr
目录中搜索匹配的文件:
find /usr -type f -name "*.conf"
Output/usr/src/linux-headers-5.4.0-88-generic/include/config/auto.conf /usr/src/linux-headers-5.4.0-88-generic/include/config/tristate.conf /usr/src/linux-headers-5.4.0-90-generic/include/config/auto.conf /usr/src/linux-headers-5.4.0-90-generic/include/config/tristate.conf /usr/share/adduser/adduser.conf /usr/share/ufw/ufw.conf /usr/share/popularity-contest/default.conf /usr/share/byobu/keybindings/tmux-screen-keys.conf /usr/share/libc-bin/nsswitch.conf /usr/share/rsyslog/50-default.conf . . .
注:上例结合了两个find
查询表达式; 即-type f
和-name "*.conf"
。 对于要返回的任何文件,它必须同时满足这两个表达式。
您可以通过使用 -and
选项将它们分开来组合这样的表达式,但是正如此示例所示,只要包含两个表达式,就会隐含 -and
。 您还可以返回满足 either 表达式的结果,方法是使用 -or
选项分隔它们:
find -name query_1 -or -name query_2
此示例将查找名称与 query_1
或 query_2
匹配的任何文件。
按时间和大小过滤
find
为您提供了多种按大小和时间过滤结果的方法。
尺寸
您可以使用 -size
参数按文件大小过滤文件。 为此,您必须在数值大小值的末尾添加一个特殊后缀,以指示您是以字节、兆字节、千兆字节还是其他大小来计算大小。 以下是一些常用的尺寸后缀:
c
:字节k
:千字节M
:兆字节G
:千兆字节b
:512 字节块
为了说明,以下命令将在 /usr
目录中查找每个正好 50 个字节的文件:
find /usr -size 50c
要查找小于 50 字节的文件,您可以改用以下语法:
find /usr -size -50c
要在 /usr
目录中查找超过 700 兆字节的文件,可以使用以下命令:
find /usr -size +700M
时间
对于系统上的每个文件,Linux 都会存储有关访问时间、修改时间和更改时间的时间数据。
- 访问时间:最后一次读取或写入文件的时间。
- 修改时间:上次修改文件内容的时间。
- 更改时间:文件的inode元数据最后一次更改。
您可以分别使用 -atime
、-mtime
和 -ctime
选项基于这些参数进行 find
搜索。 对于这些选项中的任何一个,您必须传递一个值,该值指示您想要搜索过去多少天。 与前面概述的大小选项类似,您可以在这些选项前面加上加号或减号以指定“大于”或“小于”。
例如,要查找 /usr
目录中最近一天修改的文件,请运行以下命令:
find /usr -mtime 1
如果您想要访问不到一天前的文件,您可以运行以下命令:
find /usr -atime -1
要查找最后一次更改元信息超过 3 天的文件,您可以执行以下操作:
find /usr -ctime +3
这些选项还具有可用于指定分钟而不是天的伴随参数:
find /usr -mmin -1
这将给出在最后一分钟修改过的文件。
find
还可以与参考文件进行比较并返回较新的文件:
find / -newer reference_file
此语法将返回系统上比参考文件更近创建或更改的每个文件。
按所有者和权限查找
您还可以分别使用 -user
和 -group
参数按拥有文件的用户或组搜索文件。 要查找 syslog 用户拥有的 /var
目录中的每个文件,请运行以下命令:
find /var -user syslog
同样,您可以通过键入以下内容指定 shadow 组拥有的 /etc
目录中的文件:
find /etc -group shadow
您还可以搜索具有特定权限的文件。
如果您想匹配一组精确的权限,您可以使用以下语法来指定使用八进制表示法的权限:
find / -perm 644
这将匹配具有指定权限的文件。
如果您想指定任何具有 至少 那些权限的内容,您可以在权限表示法前面加上一个减号:
find / -perm -644
这将匹配任何具有附加权限的文件。 在这种情况下,将匹配具有 744
权限的文件。
按深度过滤
在本节中,您将创建一个示例目录结构,然后您将使用该目录结构按文件在结构中的深度来探索过滤文件。
如果您按照本教程中的示例进行操作,那么在 /tmp/
目录中创建这些文件和目录是明智的。 /tmp/
是一个临时目录,意味着下次服务器启动时,其中的所有文件和目录都将被删除。 这对于本指南的目的很有用,因为您可以根据需要创建任意数量的目录、文件和链接,而不必担心它们以后会阻塞您的系统。
运行本节中的命令后,您的 /tmp/
目录将包含三级目录,第一级有十个目录。 每个目录(包括临时目录)将包含十个文件和十个子目录。
使用以下命令在 /tmp/
目录中创建示例目录结构:
mkdir -p /tmp/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}
之后,使用 touch
命令用一些示例文件填充这些目录:
touch /tmp/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}
准备好这些文件和目录后,继续导航到您刚刚创建的 test/
目录:
cd /tmp/test
要大致了解 find
将如何从此结构中检索文件,请从匹配任何名为 file1
的文件的常规名称搜索开始:
find -name file1
Output./level1dir7/level2dir8/level3dir9/file1 ./level1dir7/level2dir8/level3dir3/file1 ./level1dir7/level2dir8/level3dir4/file1 ./level1dir7/level2dir8/level3dir1/file1 ./level1dir7/level2dir8/level3dir8/file1 ./level1dir7/level2dir8/level3dir7/file1 ./level1dir7/level2dir8/level3dir2/file1 ./level1dir7/level2dir8/level3dir6/file1 ./level1dir7/level2dir8/level3dir5/file1 ./level1dir7/level2dir8/file1 . . .
这将返回很多结果。 如果将输出通过管道传输到计数器中,您会发现总共有 1111
个结果:
find -name file1 | wc -l
Output1111
在大多数情况下,这可能对您有用的结果太多。 要缩小范围,您可以指定顶级搜索目录下的最大搜索深度:
find -maxdepth num -name query
要仅在 level1
及以上目录中查找 file1
,可以指定最大深度为 2(顶级目录为 1,level1
目录为 1) :
find -maxdepth 2 -name file1
Output./level1dir7/file1 ./level1dir1/file1 ./level1dir3/file1 ./level1dir8/file1 ./level1dir6/file1 ./file1 ./level1dir2/file1 ./level1dir9/file1 ./level1dir4/file1 ./level1dir5/file1 ./level1dir10/file1
这是一个更易于管理的列表。
如果您知道所有文件都存在于当前目录下的某个点之后,您还可以指定最小目录:
find -mindepth num -name query
您可以使用它仅查找目录分支末尾的文件:
find -mindepth 4 -name file1
Output./level1dir7/level2dir8/level3dir9/file1 ./level1dir7/level2dir8/level3dir3/file1 ./level1dir7/level2dir8/level3dir4/file1 ./level1dir7/level2dir8/level3dir1/file1 ./level1dir7/level2dir8/level3dir8/file1 ./level1dir7/level2dir8/level3dir7/file1 ./level1dir7/level2dir8/level3dir2/file1 . . .
同样,由于分支目录结构,这将返回大量结果(1000)。
您可以结合最小和最大深度参数来专注于一个狭窄的范围:
find -mindepth 2 -maxdepth 3 -name file1
Output./level1dir7/level2dir8/file1 ./level1dir7/level2dir5/file1 ./level1dir7/level2dir7/file1 ./level1dir7/level2dir2/file1 ./level1dir7/level2dir10/file1 ./level1dir7/level2dir6/file1 ./level1dir7/level2dir3/file1 ./level1dir7/level2dir4/file1 ./level1dir7/file1 . . .
像这样组合这些选项可以显着缩小结果范围,只返回 110 行而不是之前的 1000 行。
在 find
结果上执行命令
您可以使用以下语法使用 -exec
参数对 find
匹配的所有内容执行任意辅助命令:
find find_parameters -exec command_and_options {} \;
{}
用作 find
匹配的文件的占位符。 \;
让 find
知道命令在哪里结束。
例如,假设您仍在上一步中在 /tmp/
目录中创建的 test/
目录中,您可以在上一节中找到具有 644
的文件权限并将它们修改为具有 664
权限:
find . -type f -perm 644 -exec chmod 664 {} \;
您还可以以类似的方式更改目录权限:
find . -type d -perm 755 -exec chmod 700 {} \;
此示例查找权限设置为 755
的每个目录,然后将权限修改为 700
。
使用 locate
查找文件
使用 find
的替代方法是 locate
命令。 此命令通常更快,并且可以轻松搜索整个文件系统。
您可以使用 apt
在 Debian 或 Ubuntu 上安装命令,方法是更新您的软件包列表,然后安装 mlocate
软件包:
sudo apt update sudo apt install mlocate
在 Rocky Linux、CentOS 和其他 RedHat 派生发行版上,您可以改为使用 dnf
命令安装 mlocate
:
sudo dnf install mlocate
locate
比 find
快的原因是它依赖于列出文件系统上所有文件的数据库。 此数据库通常每天使用 cron 脚本更新一次,但您可以使用 updatedb
命令手动更新它。 现在使用 sudo
权限运行此命令:
sudo updatedb
请记住,如果要查找新文件,locate
数据库必须始终是最新的。 如果在执行 cron 脚本之前或在运行 updatedb
命令之前添加新文件,它们将不会出现在查询结果中。
locate
允许您以多种方式过滤结果。 使用它查找文件的最基本方法是使用以下语法:
locate query
这将匹配文件路径中任何位置包含字符串 query
的任何文件和目录。 要仅返回名称包含查询本身的文件,而不是在通向它的目录中包含查询的每个文件,您可以包含 -b
标志以仅搜索“基本名称”与查询匹配的文件:
locate -b query
要让 locate
只返回文件系统中仍然存在的结果(意味着在最后一次 updatedb
调用和当前 locate
调用之间未删除的文件),请使用 [X183X ] 标志:
locate -e query
您可以使用 -S
选项检索有关 locate
已编目的信息的统计信息:
locate -S
OutputDatabase /var/lib/mlocate/mlocate.db: 21015 directories 136787 files 7727763 bytes in file names 3264413 bytes used to store database
这对于深入了解系统上存在多少文件和目录很有用。
结论
find
和 locate
命令都是在系统上查找文件的有用工具。 两者都是强大的命令,可以通过管道将它们与其他实用程序相结合来加强,但由您决定哪种工具适合您的特定情况。
从这里开始,我们鼓励您继续尝试 find
和 locate
。 您可以阅读他们各自的 man
页面以了解本指南未涵盖的其他选项,并且您可以通过将搜索结果传递到 wc
、[X207X 等其他命令来分析和操作搜索结果] 和 grep
。