Contents

按名称和扩展名查找文件

1. 概述

有时,我们可能需要按名称或特定扩展名快速找到一个文件或一组文件。虽然大多数图形文件管理器确实具有文件搜索功能,但它不如命令行上可用的搜索工具灵活和强大。

在本文中,我们将讨论一些可用于在 Linux 终端中按名称或扩展名查找文件的方法。我们将使用各种发行版附带的内置核心搜索实用程序。

2. 使用find

find 命令让我们可以搜索驱动器上的文件和目录。这是一个非常全面的实用程序,可以做很多事情。**我们不仅可以搜索文件,还可以对匹配的文件和目录进行操作。**它适用于大多数 Linux 发行版。因此,它通常是搜索时的首选工具。

让我们验证find的可用性 :

$ find --version
find (GNU findutils) 4.8.0
Packaged by Gentoo (4.8.0)
Copyright (C) 2021 Free Software Foundation, Inc.

find实用程序随findutils 软件包一起提供。如果它在系统上不可用,我们可以使用像yumapt 这样的包管理器从官方存储库安装findutils包**。

2.1. 基本文件搜索

find的基本语法很简单:

$ find [PATH] [OPTIONS] [EXPR]

默认情况下,路径是当前目录。当我们不带任何选项运行find命令时,它会列出当前目录下的所有文件和目录。假设我们要在当前目录中搜索*.zshrc文件。我们将使用-iname*测试指定它:

$ find -iname ".zshrc"
./config/zsh/.zshrc

-iname测试关闭区分大小写,而*-name测试保留区分大小写。有时,我们可能希望根据模式搜索文件。出于这个原因,我们可以使用-iregex*或 –regex 测试:

$ find -regex ".*\(zsh\|bash\)rc"
./.config/zsh/zshrc
./.config/bash/bashrc

-regex 测试指定一个模式,用于匹配文件名中包含zsh的所有文件。或者,我们可以使用*-iregex测试来禁用区分大小写。在上面的代码片段中,**正则表达式开头的 .* 用于打印文件的路径。*但是,如果我们想按扩展名搜索文件,我们可以简单地使用-name或*-iname*:

$ find -type f -iname "*.json"
./.mozilla/firefox/esr/shield-preference-experiments.json
./.mozilla/firefox/esr/extension-preferences.json
./.mozilla/firefox/esr/times.json

-type测试用于过滤匹配的类型。 在我们的例子中,我们只需要匹配文件。

2.2. 基于一组扩展的查找

有时,我们可能希望找到与一组扩展名匹配的文件。例如,搜索 PDF、EPUB 或 Markdown 文件。幸运的是,我们可以为find命令指定多个表达式:

$ find -type f -name "*.pdf" -or -name "*.epub" -or -name "*.md"
./github/haidarz/README.md
./dox/freebsd_handbook.epub
./dox/annotated_cpp.pdf
./.config/zsh/plugins/fsh/README.md
./.config/zsh/plugins/fsh/CHANGELOG.md

-or是将多个表达式链接在一起的运算符。还有其他运算符可以以相同的方式使用,例如*-not-and*。 或者,我们可以使用正则表达式编写上述命令:

$ find -iregex ".*.\(pdf\|epub\|md\)"
./github/haidarz/README.md
./dox/freebsd_handbook.epub
./dox/annotated_cpp.pdf
./.config/zsh/plugins/fsh/README.md
./.config/zsh/plugins/fsh/CHANGELOG.md

正则表达式中的“管道”字符充当*-or*运算符。

3. 使用locate

locate 命令列出了updatedb 生成的数据库中可用的文件。updatedb程序索引系统中的文件和目录并将它们保存到数据库文件 中。updatedb程序每天至少由cron 运行一次,但我们也可以从命令行手动运行它。

find相比,locate 实用程序具有更高的性能,因为它不需要遍历文件层次结构来查找文件。因此,如果我们想要获得最佳执行时间,它是首选选项。

如果它在系统上不可用,我们可以从官方存储库安装findutilsmlocate包。请注意,一旦安装了locate,我们将需要运行updatedb命令。让我们验证locate的可用性:

$ locate --version
mlocate 0.26
Copyright (C) 2007 Red Hat, Inc. All rights reserved.
This software is distributed under the GPL v.2.

3.1. 基本用法

众所周知,locate搜索整个数据库。因此,预计定位将搜索整个系统。因此,我们无法为其提供所需的搜索路径。但是,它确实提供了模式匹配选项。

首先,让我们使用updatedb命令更新文件数据库:

$ updatedb

现在,让我们搜索确切名称为xwayland的文件或路径:

$ locate xwayland -l 3
/var/db/repos/gentoo/x11-base/xwayland
/var/db/repos/gentoo/x11-base/xwayland/Manifest
/var/db/repos/gentoo/x11-base/xwayland/files

正如我们所见,它列出了名称为xwayland的文件和目录。-l或*–limit*选项限制要匹配的路径数。

3.2. 常用表达

让我们稍微改变一下前面的例子,让它只列出文件和目录,而不是包含xwayland的路径:

$ locate -r "/xwayland$"
/var/db/repos/gentoo/x11-base/xwayland

-r或*–regex选项用于指定正则表达式。在我们的例子中,我们想要列出以xwayland结尾的路径,因此表达式末尾的美元符号 ($)。我们可以指定任何符合 POSIX 的正则表达式来定位*:

$ locate --regex "\.(pdf|md|epub)$" -l 5
/usr/share/alsa/ucm/README.md
/usr/share/alsa/ucm2/README.md
/usr/share/bison/README.md
/usr/share/doc/argon2-20190702/argon2-specs.pdf
/usr/share/doc/bzip2-1.0.8-r1/manual.pdf

请注意,我们使用了*–regex而不是-r*。两个选项之间的区别在于-r用于指定基本正则表达式 (BRE) ,而–regex*标志用于指定扩展正则表达式 (ERE) *。扩展正则表达式给了我们更多的控制,因为它更全面。例如,管道功能是使用 ERE 而不是 BRE 实现的。

3.3. 缺少文件

正如我们所见,locate命令做得很好。但是,我们应该注意,默认情况下,它不关心文件的存在。如果我们要从系统中删除一个文件,我们应该知道该文件仍将在文件数据库中注册。幸运的是,locate具有处理它的*–existing-e*标志:

$ locate wgetrc
/home/hey/.config/wget/wgetrc
$ rm -rf /home/hey/.config/wget/wgetrc
$ locate wgetrc
/home/hey/.config/wget/wgetrc
$ locate -e wgetrc
$

正如我们所看到的,即使在删除wgetrc文件之后,它仍然会在结果中显示wgetrc文件,直到我们指定*-e*标志。此外,它会在文件数据库更新时解析