Linux find 命令指南

评论 0 浏览 0 2019-10-31

一、简介

Linux find 命令可用于查找磁盘上的文件和目录。它提供了多个命令行选项,使其成为一个强大的工具。在本教程中,我们将了解如何使用 find 命令。

2. 语法

让我们快速看一下 find 命令的基本语法:

find [path...] [expression]

路径表达式都是可选的。

path 参数指定一个或多个要搜索的目录。默认为当前工作目录。

表达式参数用于确定输出中包含哪些文件和目录,以及对它们采取什么操作。默认是打印所有非隐藏文件和目录。

我们将在下一节中仔细研究表达式。

请注意,不同的 Linux 发行版和版本可能使用略有不同的语法或提供不同的选项。

3. 表达式

表达式参数由选项、测试和操作组成。单个表达式可以使用传统布尔运算符(例如andor)组合任意数量的表达式。

让我们更详细地看一下每一个。

3.1.选项

选项影响find的整体操作,而不是搜索过程中对特定文件的处理。

一些最重要的选项是:

  • -d-depth:执行深度优先遍历,先处理子目录,再处理目录中的文件
  • -daystart:测量时间从一天开始而不是 24 小时前开始
  • -help:打印简单的命令行用法,然后退出
  • -mindepth-maxdepth:控制停止前搜索的目录层数(默认 mindepth 为0, maxdepth 默认为无限制)

3.2.测试

测试是 find 命令的核心。 应用于找到的每个文件,测试将返回 truefalse,具体取决于该特定文件是否通过。

我们可以使用测试来查看各种文件属性,例如修改时间、模式匹配、权限、大小等。让我们看看我们可以执行的一些更流行的测试。

首先,有按名称或类型匹配文件的测试:

  • -name:测试文件名是否与模式匹配(使用简单的模式匹配,只查看文件名)
  • -regex:测试文件名是否与模式匹配(使用标准 Emacs 正则表达式并查看完整文件路径)
  • -type:测试文件是否为特定类型(常规文件、目录、符号链接等)

让我们使用 find-name 测试来查找当前目录中的所有 XML 文件:

> find . -name "*.xml"
src/main/resources/applicationContext.xml
src/test/resources/applicationContext-test.xml

请注意,默认输出只是每个文件的完整路径。

现在,让我们只查找 /tmp 目录中的目录:

find /tmp -type d

还有一些测试可以使用时间比较来匹配文件

  • -amin-anewer-atime:根据相对时间或其他文件测试文件的最后访问时间
  • -cmin-cnewer-ctime:根据相对时间或其他文件测试文件的最后创建时间
  • -mmin-mnewer-mtime:根据相对时间或其他文件测试文件的最后修改时间
  • -newer:测试文件是否比另一个文件新

下面是一个示例 find 命令,它使用 –ctime 来查找去年在名为 lib 的目录中创建的所有 JAR 文件:

find lib -name "*.jar" -ctime -365

或者,我们可以查找当前目录中比名为 testfile 的文件更新的所有文件:

find . -newer testfile

其他一些方便的测试可以根据权限或大小等其他文件属性进行匹配

  • -perm:测试文件权限是否与给定的权限模式匹配
  • -size:测试文件的大小

在这里,我们将使用-perm来查找当前目录中与权限模式700匹配的所有文件:

find . -perm 700

让我们使用 -size 来查找名为 properties 的目录中所有大于 1 KB 的文件:

find properties -size 1k

3.3.操作

对符合所有测试的文件执行操作。默认操作是简单打印文件名和路径。

我们还可以使用其他一些操作来打印有关匹配文件的更多详细信息

  • -ls:执行文件的标准目录列表
  • -print-print0-printf:将详细信息打印到标准输出
  • -fprint-fprint0-fprintf:将文件的详细信息打印到文件中

为了进行演示,我们使用 -ls 操作来执行 target 目录中所有 .jar 文件的目录列表:

> find target -name "*.jar" -ls
4316430646    88112 -rw-r--r--    1 mike staff 45110374 Oct 14 15:01 target/app.jar

我们可以使用 -printf 和格式字符串来仅打印每行的文件大小和名称:

> find lib -name "*.jar" -printf '%s %p\n'
12345 file1.jar
24543 file2.jar

我们可以与 find 命令一起使用的一些更高级操作是:

  • -delete:从磁盘中删除文件
  • -exec:执行任意命令

假设我们要删除 /tmp 目录中的所有 .tmp 文件:

find /tmp -name "*.tmp" -delete

或者查找所有包含单词“interface”的 .java 文件:

find src -name "*.java" -type f -exec grep -l interface {} \;

注意末尾的";"。这会导致 grep 命令逐个文件执行(“\”是必需的,因为 shell 会解释分号)。我们还可以使用“+”来代替,这会导致多个文件同时传递到 grep 中。

-exec 命令的替代方法是将输出传输到xargs。 xargs 命令从标准输入中获取项目并在这些输入上执行给定的命令。让我们使用 xargs 重写上面的命令:

find src -name "*.java" -type f | xargs grep -l interface

虽然结果相同,但执行速度却存在显着差异。让我们对 -exec版本 计时 :

time find src -name "*.java" -type f -exec grep -l interface {} \;

返回:

8.39s user
20.43s system 
84% cpu 
34.048 total

现在,如果我们 time 使用 xargs:

time find src -name "*.java" -type f | xargs grep -l interface

我们看:

find src -name "*.java" -type f 
0.13s user 
0.96s system 
70% cpu 
1.552 total
xargs grep -l interface
0.62s user 
0.42s system 
58% cpu 
1.794 total

使用 xargs 最终会快得多。速度的提高是因为xargs本质上是对一批输入进行操作,其大小由xargs本身决定,而-execfind的每个结果执行grep,一次一个。

3.4.运算符

上面的所有表达式类型都可以使用传统的布尔运算符进行组合。

以下是受支持运算符的快速列表(按优先顺序排列):

  • (expr):强制执行括号内的表达式,然后再执行其他表达式;注意使用引号避免 shell 插值
  • !, -not:否定表达式;注意使用引号避免 shell 插值
  • -a-and:对两个表达式执行布尔 and 运算,仅当两个表达式都为true时才返回true
  • -o-or:对两个表达式执行布尔 or 运算,如果其中一个表达式为true,则返回true

例如,我们可以在 src 目录中找到任何不是目录的文件

find src ! -type d

或者我们可以在 properties 目录中找到所有带有 .xml.yaml 扩展名的文件

find properties -name "*yaml" -o -name "*.xml"

4. 高级选项

除了路径和表达式之外,大多数版本的 find 还提供更多高级选项:

find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path] [expressions]

首先,-H-L-P 选项指定find 命令如何处理符号链接。默认使用-P,这意味着测试将使用链接本身的文件信息。

-O 选项用于指定查询优化级别。此参数更改find重新排序表达式的方式,以帮助加快命令速度而不更改输出。我们可以指定 0 到 3 之间的任何值(含 0 和 3)。默认值为 1,这足以满足大多数用例。

最后,-D选项指定调试级别 - 它打印诊断信息,可以帮助我们诊断find命令未按预期工作的原因。

5. 结论

在本教程中,我们了解了如何使用 Linux find 命令。

通过使用表达式和布尔逻辑的组合,find命令可以帮助我们高效地定位文件和目录。

简而言之,find 命令本身就足够强大,但与其他 Linux 命令结合使用时,它是最有用的命令行工具之一。

最后更新2023-07-27
0 个评论
标签