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


10

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

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

cd /d C:\
dir *filename* /s

什么是Linux等效产品?


嗯,有相当明显的对皮肤的方法不止一种这样的猫。我还是有点好奇,想知道是否有办法做到这一点ls
Iszi 2011年

Answers:


13
locate filename
find -name '*filename*'
echo **/*filename*
ls -ld **/*filename*

(请继续阅读以了解主要条款和条件。请阅读手册以获取详细信息。)

列出目录的内容是的一种辅助功能ls。,它的主要工作是解决ls其大部分复杂问题,它是对显示进行微调。(查看手册,比较与选择要显示的文件有关的选项数量与控制要显示有关每个文件的信息以及如何格式化显示的选项数量。这对于您所使用的GNU ls都是正确的从早期开始,就可以在Linux以及其他选项较少的系统上找到。)

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

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

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

echo *filename*

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

echo **/*filename*

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

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

find -name '*filename*'

当您知道文件名(的一部分)时,另一个有用的工具是locate。该工具查询文件名数据库。在典型的系统上,它每晚都会刷新。locateover 的优点find /是速度更快。不利的一面是其信息可能过时。locate在多用户系统上,有几种实现方式不同,它们的行为不同:基本locate程序仅索引可公开读取的文件(您可能希望运行协同程序updatedb以建立第二个数据库来索引帐户中的所有文件);还有其他版本(mlocate,slocate)可对所有文件建立索引,并使locate程序对数据库进行过滤以仅返回您可以看到的文件。

locate filename

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


希望我能再次投票赞成。今晚只需要查找另一个项目。再次感谢@Gilles!
Iszi 2012年

6

与您的DOS示例等效的是:

cd /
find . -name \*filename\* -print

但是,在Linux上,您通常-print不再需要该参数。如果您发现自己在其他操作系统上工作,则很容易知道。


5

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

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

如果您认为需要在下一次cron更新之前使数据库更新,则它通常比findls仅运行sudo updatedb然后快locate。如果您需要进行更多搜索,绝对可以更快...顾名思义,updatedb更新locate使用... 的数据库。

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

locate 返回匹配文件的标准路径。


2
find [path] -name [filename]

例如,如果要在/ home目录中搜索包含foo的文件名,则可以使用以下命令:

find /home -name *foo*

使用该命令man find获取有关find命令和参数的更多信息,


3
您需要引用或转义*s以防止shell解释它们。
肖恩·高夫

该发行版/外壳特定吗?我在Fedora 16中成功运行了它,并且运行良好。
josh-cain

1
如果某些壳没有匹配项,则某些shell中会有一些选项将星传递给程序。尝试在当前目录中创建与该模式匹配的文件,然后重试该命令。
肖恩·高夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.