如何从命令行在文件系统中查找文件?

Isz*_*szi 10 ls ubuntu find locate

我想找到一个文件(具有部分已知的文件名)在文件系统中的位置。我想知道如何从命令行执行此操作,而不是使用 GUI 实用程序。

在 Windows 中,我会运行以下命令:

cd /d C:\
dir *filename* /s
Run Code Online (Sandbox Code Playgroud)

Linux 等价物是什么?

Gil*_*il' 13

locate filename
find -name '*filename*'
echo **/*filename*
ls -ld **/*filename*
Run Code Online (Sandbox Code Playgroud)

(继续阅读主要条款和条件。阅读手册以获得细则。)

列出目录的内容是ls. 的主要工作ls,占据了其大部分复杂性,是微调其显示。(查看手册并比较与选择要显示的文件相关的选项数量与控制显示有关每个文件的信息以及显示格式的选项数量。这对于您的GNU ls都是正确的会在 Linux 和其他选择较少的系统上找到,从早期开始。)

的默认模式ls是,当您向它传递目录时,它会列出该目录中的文件。如果您将任何其他类型的文件(常规文件、符号链接等)传递给它,它只会列出该文件。(这分别适用于每个参数。)该选项-d告诉ls永远不要进入目录。

ls确实有一个选项-R告诉它递归地列出目录。但它的适用性有限,并且不允许对输出进行太多过滤。

执行模式匹配的第一个工具是 shell 本身。您不需要任何其他命令:只需输入通配符即可设置。这就是所谓的通配符

echo *filename*
Run Code Online (Sandbox Code Playgroud)

传统上,通配符仅限于当前目录(或指定的目录:)echo /some/where/*filename*。A*匹配任何文件名或文件名的任何部分,但*.txt不会匹配foo/bar.txt. 现代 shell 添加了模式**/,意思是“在这个目录中,或者在它下面的任何目录中(递归地)”。对于 bash,出于历史兼容性原因,需要显式启用此功能shopt -s globstar(您可以将此行放在您的~/.bashrc)中。

echo **/*filename*
Run Code Online (Sandbox Code Playgroud)

echo命令只是将 shell 生成的文件名列表回显给您。作为一个例外,如果根本没有匹配的文件名,则通配符模式在 bash 中保持不变(除非您设置了shopt -s nullglob,在这种情况下模式扩展为空列表),并且 zsh 发出错误信号(除非您设置了setopt nullglob,或setopt no_no_match这导致模式保持不变)。

您可能仍想使用ls它的选项。例如,ls可以通过颜色指示文件(目录、可执行文件等)的性质或权限。您可能希望显示文件的日期、大小和所有权ls -l。有关更多选项,请参阅手册。

在目录树中查找文件的传统命令是find. 它带有许多选项来控制要显示哪些文件以及如何处理它们。例如,要*filename*在当前目录及其子目录中查找名称与模式匹配的文件并打印它们的名称:

find /some/dir -name '*filename*' -print
Run Code Online (Sandbox Code Playgroud)

-print是一个动作(大多数其他动作包括对文件执行命令);如果您不采取行动,-print则是隐含的。此外,如果您没有指定要遍历的任何目录(/some/dir如上),则隐含当前目录。条件-name '*filename'表示仅列出(或操作)名称与该模式匹配的文件;还有许多其他过滤器,例如-mtime -1匹配过去 24 小时内修改的文件。您有时可以省略 上的引号-name '*filename*',但前提是通配符不匹配当前目录中的任何文件(见上文)。总而言之,简短的形式是

find -name '*filename*'
Run Code Online (Sandbox Code Playgroud)

当您知道(部分)文件名称时,另一个有用的工具是locate. 此工具查询文件名数据库。在典型的系统上,它每晚都会刷新。locateover的优点find /是它要快得多。一个缺点是它的信息可能是陈旧的。有几种实现locate在多用户系统上的行为有所不同:基本locate程序仅索引公开可读的文件(您可能需要运行配套程序updatedb来创建第二个数据库来索引您帐户中的所有文件);还有其他版本(mlocate、slocate)可以索引所有文件并让locate程序过滤数据库以仅返回您可以看到的文件。

locate filename
Run Code Online (Sandbox Code Playgroud)

有时您认为文件是由您的发行版中的包提供的,您知道(部分)文件的名称但不知道包的名称,并且您想安装该包。许多发行版为此提供了工具。在 Ubuntu 上,它是apt-file search filename. 对于其他系统上的等效命令,请查看Pacman Rosetta


Tim*_*edy 6

相当于您的 DOS 示例将是:

cd /
find . -name \*filename\* -print
Run Code Online (Sandbox Code Playgroud)

不过,在 Linux 上,您通常-print不再需要该参数。如果您发现自己在其他操作系统上工作,了解它会很方便。


Pet*_*r.O 5

如果你想要一些“快速”的东西,但不是在关键任务的情况下,你只想知道它是否存在以及它在哪里,你可以使用locate. 它在您告诉它收集信息的目录中保存所有文件的数据库。

在默认安装中(在 Ubuntu 上),locate设置每天cron扫描文件系统并更新数据库的作业...

如果您觉得需要在下一次 cron 更新之前更新数据库,它通常比运行findls仅运行sudo updatedb然后locate. 如果您需要进行更多搜索,它肯定会更快……顾名思义,updatedb更新locate使用……的数据库。

locate具有内置的正则表达式,这使得它非常方便......我将find在脚本中使用,但我很少find在命令行中使用。我什至locate在(个人)脚本中使用......例如。locate -bir "oo.*datt.*mp4$"

locate 返回匹配文件的完全限定路径。