find
===

在指定目录下查找文件

## 解释

从每个指定的起始点 (目录) 开始，搜索以该点为根的目录树，并按照运算符优先级规则**从左至右**评估给定的表达式，直到结果确定，此时`find`会继续处理下一个文件名。

## 补充说明

本文列出的选项指的是**表达式列表中的选项**。这些选项控制了`find`的行为，需在**最后一个路径名之后**立即指定。

五个真实选项: `-H、-L、-P、-D 和 -O`。如果出现，**必须位于第一个路径名之前**。关于这部分内容本文不做描述，具体内容可参考[man7.org中的find](https://man7.org/linux/man-pages/man1/find.1.html#top_of_page)

如果使用该命令时，不设置任何参数，则`find`命令将在当前目录下查找子目录与文件，并且将查找到的子目录和文件全部进行显示。等效于以下命令:
```shell
find . -print
```

## 语法

```shell
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [起始点...] [表达式]
```

忽略真实选项后 (更为常见): 
```shell
find [起始点...] [表达式]
```

## 表达式分类
起始点（列表）之后的部分是表达式。这是一种**查询规范**，描述了我们如何匹配文件（返回**真**或者**假**）以及对匹配到的文件进行何种操作。表达式由一系列元素组成：
- 测试（Tests）：测试返回一个真或假值，通常基于我们正在考虑的文件的某个属性。例如，`-empty`测试仅在当前文件为空时为真。
- 操作（Actions）：操作具有副作用（例如在标准输出上打印内容），并返回真或假，通常基于它们是否成功。例如，`-print`操作会在标准输出上打印当前文件的名称。
- 全局（Global）：全局选项影响命令行中任何部分指定的测试和操作的执行。全局选项始终返回真值。例如，`-depth`选项使find以深度优先的顺序遍历文件系统。
- 位置（Positional）：位置选项仅影响其后的测试或操作。位置选项始终返回真值。例如，`-regextype`选项是位置选项，用于指定命令行中后续正则表达式所使用的正则表达式方言。
- 操作符（Operators）：运算符将表达式中的其他项连接起来。例如，它们包括`-o`（表示逻辑或）和`-a`（表示逻辑与）。如果缺少运算符，则默认使用`-a`。

## 表达式选项

### 测试选项
```shell
-amin<分钟>：查找在指定时间曾被存取过的文件或目录，单位以分钟计算；
-anewer<参考文件或目录>：查找其存取时间较指定文件或目录的存取时间更接近现在的文件或目录；
-atime<24小时数>：查找在指定时间曾被存取过的文件或目录，单位以24小时计算；
-cmin<分钟>：查找在指定时间之时被更改过的文件或目录；
-cnewer<参考文件或目录>查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录；
-ctime<24小时数>：查找在指定时间之时被更改的文件或目录，单位以24小时计算；
-empty：寻找文件大小为0 Byte的文件，或目录下没有任何子目录或文件的空目录；
-executable 匹配当前用户可执行的文件和可搜索的目录。
-false：将find指令的回传值皆设为False；
-fstype<文件系统类型>：只寻找该文件系统类型下的文件或目录；
-gid<群组识别码>：查找符合指定之群组识别码的文件或目录；
-group<群组名称>：查找符合指定之群组名称的文件或目录；
-ilname<范本样式>：此参数的效果和指定“-lname”参数类似，但忽略字符大小写的差别；
-iname<范本样式>：此参数的效果和指定“-name”参数类似，但忽略字符大小写的差别；
-inum<inode编号>：查找符合指定的inode编号的文件或目录；
-ipath<范本样式>：此参数的效果和指定“-path”参数类似，但忽略字符大小写的差别；
-iregex<范本样式>：此参数的效果和指定“-regexe”参数类似，但忽略字符大小写的差别；
-iwholename 模式参见`-ipath`。此选项的可移植性较`-ipath`差。
-links<连接数目>：查找符合指定的硬连接数目的文件或目录；
-lname<范本样式>：指定字符串作为寻找符号连接的范本样式；
-mmin<分钟>：查找在指定时间曾被更改过的文件或目录，单位以分钟计算；
-mtime<24小时数>：查找在指定时间曾被更改过的文件或目录，单位以24小时计算；
-name<范本样式>：指定字符串作为寻找文件或目录的范本样式；
-newer<参考文件或目录>：查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录；
-newerXY<引用>：如果正在考虑的文件的时间戳 X 比文件引用的时间戳 Y 更新则成功。
-nogroup：找出不属于本地主机群组识别码的文件或目录；
-nouser：找出不属于本地主机用户识别码的文件或目录；
-path<范本样式>：指定字符串作为寻找目录的范本样式；
-perm<权限数值>：查找符合指定的权限数值的文件或目录；
-readable：匹配当前用户可读的文件
-regex<范本样式>：指定字符串作为寻找文件或目录的范本样式；
-samefile 名称 文件与名称指向相同的 inode。
-size<文件大小>：查找符合指定的文件大小的文件；
-type<文件类型>：只寻找符合指定的文件类型的文件；
-uid<用户识别码>：查找符合指定的用户识别码的文件或目录；
-used<日数>：查找文件或目录被更改之后在指定时间曾被存取过的文件或目录，单位以日计算；
-user<拥有者名称>：查找符和指定的拥有者名称的文件或目录；
-writable：匹配当前用户可写入的文件。
-xtype<文件类型>：此参数的效果和指定“-type”参数类似，差别在于它针对符号连接检查。
-context<表达式>：仅限 SELinux。文件的安全上下文与全局模式匹配
```

### 操作选项

#### -delete 删除文件或目录。
> :warning:警告：find 命令会将命令行作为表达式进行解析，因此将`-delete`放在首位会将指定的起始点下的**所有内容删除**。且`-delete`操作无法删除一个目录，除非它是空的。

##### *无参数*

##### 描述
如果删除成功则返回真。若删除失败，将显示错误消息，并且 find 最终退出时的状态码将为非零。

##### 相关选项
- **-depth**：在命令行中使用`-delete`操作会自动启用`-depth`选项。为了避免意外情况，通常最好在早期的**Tests选项**中**明确使用**`-depth`选项。
- **-prune**：由于`-depth`会使`-prune`失效，因此`-delete`操作无法与`-prune`有效结合使用。通常，用户可能希望在实际删除操作前，先用带有`-print`的查找命令行进行测试，以确保在添加`-delete`进行实际删除时不会出现意外结果。
- **-ignore_readdir_race**：`-delete`与此选项一起使用时，find 会忽略自父目录读取以来文件已消失的情况下`-delete`操作的错误：它不会输出错误诊断，不会将退出代码更改为非零，并且`-delete`操作的返回代码将为真。

#### -exec 执行命令

> :warning:警告：使用`-exec`操作存在不可避免的安全问题，应改用`-execdir`选项。

##### 参数
`command ;` 或 `command {} +`

##### 描述
如果返回状态为 0，则结果为真。**注意**：find 命令会将**所有后续参数**视为`command`的参数，直到遇到包含`;`的参数为止。字符串`{}`会在`command`的参数中所有出现的位置被替换为当前正在处理的文件名，而不仅仅是在它单独出现的参数中，这与某些版本的 find 不同。这两种结构可能需要使用反斜杠`\`或引号来转义，以防止被 shell 扩展。指定的命令会为每个匹配的文件运行一次。命令在起始目录中执行。

#### -execdir 在包含匹配文件的子目录中执行命令

##### 参数
`command ;` | `command {} +`

##### 描述
类似于`-exec`，但指定的`command`会在包含匹配文件的**子目录中运行**，而非find的起始点目录。与`-exec`一样，如果从shell调用find，`{}`应加引号。这是一种更安全的调用`command`方式，因为它避免了在解析匹配文件路径时出现的竞争条件。与`-exec`操作类似，`+`形式的`-execdir`会构建一个命令行来处理多个匹配文件，但任何给定的`command`调用只会列出存在于同一子目录中的文件。如果使用此选项，必须确保 PATH 环境变量未引用`.`，否则攻击者可以通过在您将运行`-execdir`的目录中留下一个适当命名的文件来运行任何命令。同样，PATH 中的条目**不应为空**或**非绝对目录名**。如果使用`+`形式的任何调用以非零值作为退出状态返回，则 find 也会返回非零退出状态。如果 find 遇到错误，有时会导致立即退出，**因此某些待处理的command可能根本不会运行**。 操作结果取决于使用的是`+`还是`;`变体。`-execdir command {} + `总是返回真，而  `-execdir command {} ;`仅在命令返回 0 时返回真。

#### -fls 创建文件并将结果写入文件

##### 参数
`file`

##### 描述
此选项始终返回真。`-fls`类似于`-ls`和`-fprint`，但`-fls`会将结果写入文件中。无论谓词是否匹配，输出文件始终会被创建。有关文件名中特殊字符处理的信息，请参阅“特殊文件名处理”部分。

#### -fprint 将完整文件名打印到指定文件中

##### 参数
`file`

##### 描述
此选项始终返回真。若运行 find 时`file`不存在，则创建该`file`；若`file`已存在，则截断其内容。文件名`/dev/stdout`和`/dev/stderr`有特殊处理，分别指向标准输出和标准错误输出。即使谓词从未匹配，输出文件也会始终创建。

#### -fprint0

##### 参数
`file`

##### 描述
此选项始终返回真。类似于`-print0`，但将输出写入文件；类似于`-fprint`。即使谓词从未匹配，输出文件也始终会被创建。

#### -fprintf

##### 参数
`file`

##### 描述
此选项始终返回真。类似于`-printf`，但将输出写入文件；类似于`-fprint`，即使谓词从未匹配，输出文件也会始终创建。

#### -ls 列出当前文件并输出到标准输出

##### *无参数*

##### 描述
此选项始终返回真。以`ls -dils`格式列出当前文件并输出到标准输出。块计数为 1 KB 块，除非设置了环境变量 POSIXLY_CORRECT，此时使用 512 字节块。

#### -ok 执行命令前询问用户

##### 参数
`command ;`

##### 描述
类似于`-exec`，但首先会询问用户。如果用户同意，则运行该命令；否则仅返回 false。若运行该命令，其标准输入将被重定向至`/dev/null`。对提示的响应会与一对正则表达式进行匹配，以确定其为肯定或否定回答。若设置POSIXLY_CORRECT 环境变量，则该正则表达式从系统获取；否则，从 find 的消息翻译中获取。如果系统没有合适的定义，将使用 find 自身的定义。无论哪种情况，正则表达式本身的解释都会受到环境变量 LC_CTYPE（字符类）和 LC_COLLATE（字符范围和等价类）的影响。

##### 相关选项
- **-files0-from**：不能与`-ok`同时指定。

#### -okdir

##### 参数
`command ;`

##### 描述
类似于`-execdir`，但在执行前会以与`-ok`相同的方式询问用户。如果用户不同意，则直接返回 false。如果命令被执行，其标准输入将从`/dev/null`重定向。

##### 相关选项
- **-files0-from**：不能与`-okdir`同时指定。

#### -print 打印完整文件名，后跟一个换行符

##### *无参数*

##### 描述
此选项始终返回真。如果你将 find 的输出通过管道传输到另一个程序，并且你正在搜索的文件可能包含换行符，那么应该考虑使用`-print0`而不是`-print`。

#### -print0 打印完整文件名，后跟一个空字符

##### *无参数*

##### 描述
此选项始终返回真。包含换行符或其他类型空白字符的文件名能被正确解析，以便处理 find 输出的程序能正确理解。此选项对应于`xargs`的`-0`选项。

#### -printf 打印格式

##### 参数
`format`

可用的转义字符和指令包括：
- \a 警报。
- \b 退格键。
- \c 立即停止打印并清空输出。
- \f 换页。
- \n 换行。
- \r 回车符。
- \t 水平制表符。
- \v 垂直制表符。
- \0 空字符。
- \\\ 一个字面的反斜杠`\`。
- \NNN 字符，其 ASCII 码为 NNN（八进制）。
- A 一个反斜杠字符`\`后跟任何其他字符，都会被视为普通字符，因此它们都会被打印出来。
- %% 一个字面的百分号。
- %a 文件的最后访问时间，格式为 C 语言 ctime(3)函数返回的样式。
 .....更多内容待补充

##### 描述
*暂无*

#### -prune 如果文件是目录，则不进入该目录

##### *无参数*

##### 描述
此选项始终返回真。

##### 相关选项
- **-depth**：如果指定了`-depth`，那么`-prune`将无效。
- **-delete**：因为`-delete`隐含了`-depth`，所以不能有效地同时使用两者。

#### -quit 立即退出

##### *无参数*

##### 描述
如果没有发生错误，则返回值为零。这与`-prune `不同，因为`-prune`仅适用于被修剪目录的内容，而`-quit`则使 find 立即停止。不会有任何子进程继续运行。在程序退出之前，任何通过`-exec ... +`或`-execdir ... +`构建的命令行都会被调用。执行`-quit`后，命令行中指定的文件将不再被处理。例如，`find /tmp/foo /tmp/bar -print -quit`将仅打印 `/tmp/foo`。`-quit`的一个常见用途是在找到所需内容后停止搜索文件系统。

### 全局选项
始终返回真值。全局选项对命令行中较早出现的测试也会生效。为避免混淆，全局选项应在命令行上列出**起始点之后、第一个测试选项、位置选项或操作选项之前指定**。若在其他位置指定全局选项，find 会发出警告消息，说明这可能引起混淆。

> 全局选项出现在起始点列表之后，因此与例如`-L` 这样的选项不属于同一类别。

#### -d `-depth`的同义词

##### *无参数*

##### 描述
仅用于与 FreeBSD、NetBSD、MacOS X 和 OpenBSD 兼容。

#### -depth 遍历级别

##### 参数
`levels`

##### 描述
在处理目录本身之前，先处理目录中的内容。`-delete`操作也隐含了`-depth`。

#### -files0-from 从文件中读取起始点，而非通过命令行获取。

##### 参数
`file`

##### 描述

使用此选项可以安全地给 find 命令传递任意数量的起始点。使用此选项和在命令行中传递起始点**是互斥的**，因此不允许同时进行。文件参数是强制性的。文件中的起始点必须用 ASCII NUL 字符分隔。两个连续的 NUL 字符，即带有零长度文件名的起始点是不允许的，这将导致错误诊断，并随后产生非零退出码。

与标准调用不同，在标准调用中，如果没有传递路径参数，find 会默认将当前目录作为起始点。起始点的处理方式与其他情况相同，例如，find 命令会递归进入子目录，除非另有阻止。若要仅处理起始点，可以额外传递`-maxdepth 0`参数。

**其他说明**：如果一个文件在输入文件中被列出多次，则其是否会被多次访问未作规定。如果在查找操作期间文件被修改，结果同样未作规定。最后，find 退出时（无论是通过`-quit`还是其他方式），命名文件中的查找位置也未作规定。此处**未作规定**意味着它**可能有效也可能无效**，**或者不做任何特定的事情**，并且该行为可能因平台或 findutils 版本而异。

> :bulb:可以使用`-files0-from`**从标准输入流中读取起始点列表**，例如从管道中读取。在这种情况下，不允许使用`-ok`和`-okdir`操作，因为它们会干扰从标准输入读取以获取用户确认。

> :warning:警告：如果给定文件为空，find 不会处理任何起始点，因此在解析完程序参数后会立即退出。

#### -help 和 --help 打印 find 命令行用法的摘要并退出。

##### *无参数*

##### 描述
*无描述*

#### -ignore_readdir_race

##### *无参数*

##### 描述
通常情况下，当 find 无法对文件进行状态检查（stat）时，会发出错误消息。如果您**启用此选项**，并且在 find 从目录读取文件名，到尝试进行状态检查**之间的时间内文件被删除**，则不会发出任何错误消息。这也适用于命令行中指定的文件或目录。此选项在命令行读取时生效，这意味着您不能在文件系统的某部分启用此选项，而在另一部分禁用它（如果需要这样做，您需要发出两个 find 命令，一个启用选项，一个不启用）。此外，使用`-ignore_readdir_race`选项时，如果在读取父目录后文件已消失，find 命令将忽略`-delete`操作的错误：它不会输出错误诊断信息，并且`-delete`操作的返回码将为真。

####  -maxdepth 最大遍历级别

##### 参数
`levels`

##### 描述
最多向下遍历 levels 级（一个非负整数）目录层级。使用`-maxdepth 0`表示**仅对起始点本身**应用测试和操作。

#### -mindepth 最小遍历级别

##### 参数
`levels`

##### 描述
在小于指定级别（非负整数）的层级上不执行任何测试或操作。使用`-mindepth 1`表示处理**除起始点外的所有文件**。

#### -mount 不在其他文件系统中下降目录

##### *无参数*

##### 描述
这是`-xdev`的替代名称，用于与其他一些版本的 find 兼容。

#### -noignore_readdir_race

##### *无参数*

##### 描述
关闭了`-ignore_readdir_race`的效果。

#### -noleaf 不进行优化。

##### *无参数*

##### 描述
不通过假设目录包含比其硬链接数少 2 个子目录来进行优化。在搜索不遵循 Unix 目录链接惯例的文件系统时，需要此选项，例如 CD-ROM、MS-DOS 文件系统或 AFS 卷挂载点。在正常的 Unix 文件系统上，每个目录至少有 2 个硬链接：其名称及其`.`条目。此外，其子目录（如果有）各自有一个指向该目录的`..`条目。当 find 检查一个目录时，在它已经统计了比目录链接数少 2 个子目录之后，它知道该目录中的其余条目是非目录（目录树中的“叶”文件）。如果只需要检查文件的名称，则无需对其进行状态检查；这可以显著提高搜索速度。

#### -version 和 --version 打印 find 的版本号并退出。

##### *无参数*

##### 描述
*无描述*

#### -xdev 不进入其他文件系统的目录。

##### *无参数*

##### 描述
*无描述*

### 位置选项
始终返回真值。它们仅影响命令行中后续的测试。

#### -daystart 从今天开始

> 用于 `-amin`、`-atime`、`-cmin`、`-ctime`、`-mmin` 和 `-mtime`

##### *无参数*

##### 描述
从今天开始而非从 24 小时前开始。此选项仅影响命令行中后续出现的测试。

#### ~~-follow~~ 解引用符号链接。

##### *无参数*

##### 描述
**已弃用，请改用`-L`选项**。隐含`-noleaf`。`-follow`选项仅影响命令行中出现在其后的那些测试。除非已指定`-H`或`-L`选项，否则`-follow`选项的位置会改变`-newer`谓词的行为；作为`-newer`参数列出的任何文件，如果它们是符号链接，则会被解引用。同样的情况适用于`-newerXY`、`-anewer`和`-cnewer`。类似地，`-type `谓词将始终匹配符号链接所指向的文件类型，而非链接本身。使用`-follow`会导致  `-lname`和`-ilname`谓词始终返回 false。

#### -regextype 更改正则表达式语法

##### 参数
`type`

##### 描述
更改`-regex`和`-iregex`测试在命令行后续部分所理解的正则表达式语法。要查看已知的正则表达式类型，请使用`-regextype help`。Texinfo 文档解释了各种正则表达式类型的含义及其差异。如果您不使用此选项，find 的行为如同已指定正则表达式类型为`emacs`。

#### -warn 和 -nowarn 开启或关闭警告消息。

##### *无参数*

##### 描述
这些警告仅适用于命令行使用，不适用于 find 在搜索目录时可能遇到的情况。默认行为是：如果标准输入是`tty`，则对应`-warn`；否则对应`-nowarn`。如果产生与命令行使用相关的警告消息，find 的退出状态不受影响。如果设置了 POSIXLY_CORRECT 环境变量，并且也使用了`-warn`，则未指定哪些（如果有）警告会被激活。

### 运算符选项
运算符按优先级递减顺序列出：
- `(expr)` 强制优先级。由于括号对 shell 有特殊含义，通常需要对它们进行引用。许多示例为此使用了反斜杠：`\(...\)` 而非 `(...)`。
- `! expr` 若表达式为假则结果为真（取反）。此字符通常也需要防止被 shell 解释。

> :bulb:提示：当`-a`隐式指定（例如两个测试之间没有显式运算符）或显式指定时，其优先级高于`-o`。例如，`find . -name foo -o -name bar -print`永远不会打印`foo`。

#### -not

##### 参数
`expr`

##### 描述
等同于`! expr`，但不符合 POSIX 标准。

#### -a 

##### 参数
`expr1` -a `expr2`

##### 描述
两个连续的表达式被视为隐含地用`-a`连接；如果`expr1`为假，则不评估`expr2`。等同于`expr1 expr2`。

#### -and

##### 参数
`expr1` -and `expr2`

##### 描述
与`-a`相同。但不符合 POSIX 标准。

#### -o

##### 参数
`expr1` -o `expr2`

##### 描述
`expr1`和`expr2`始终都会被评估。`expr1`的值会被丢弃；列表的值即为`expr2`的值。逗号运算符（`,`）在搜索多种不同类型的事物时非常有用，但只会遍历文件系统层次结构一次。`-fprintf`动作可用于将各种匹配项列出到多个不同的输出文件中。若`expr1`为真，则不评估`expr2`。
#### -or

##### 参数
`expr1` -or `expr2`

##### 描述
与`-o`相同。但不符合 POSIX 标准。

## 例子

当前目录搜索所有文件，且文件内容包含 “140.206.111.111” 
```shell
find . -type f -name "*" | xargs grep "140.206.111.111"
```

#### 根据文件或者正则表达式进行匹配

列出当前目录及子目录下所有文件和文件夹

```shell
find .
```

在`/home`目录下查找以.txt结尾的文件名

```shell
find /home -name "*.txt"
```

同上，但忽略大小写

```shell
find /home -iname "*.txt"
```

当前目录及子目录下查找所有以.txt和.pdf结尾的文件

```shell
find . \( -name "*.txt" -o -name "*.pdf" \)

或

find . -name "*.txt" -o -name "*.pdf"
```

匹配文件路径或者文件

```shell
find /usr/ -path "*local*"
```

基于正则表达式匹配文件路径

```shell
find . -regex ".*\(\.txt\|\.pdf\)$"
```

同上，但忽略大小写

```shell
find . -iregex ".*\(\.txt\|\.pdf\)$"
```

#### 否定参数

找出/home下不是以.txt结尾的文件

```shell
find /home ! -name "*.txt"
```

#### 根据文件类型进行搜索

```shell
find . -type 类型参数
```

类型参数列表：

*    **f**  普通文件
*    **l**  符号连接
*    **d**  目录
*    **c**  字符设备
*    **b**  块设备
*    **s**  套接字
*    **p**  Fifo

#### 基于目录深度搜索

向下最大深度限制为3

```shell
find . -maxdepth 3 -type f
```

搜索出深度距离当前目录至少2个子目录的所有文件

```shell
find . -mindepth 2 -type f
```

#### 根据文件时间戳进行搜索

```shell
find . -type f 时间戳
```

UNIX/Linux文件系统每个文件都有三种时间戳：

*    **访问时间** （-atime/天，-amin/分钟）：用户最近一次访问时间。
*    **修改时间** （-mtime/天，-mmin/分钟）：文件最后一次修改时间。
*    **变化时间** （-ctime/天，-cmin/分钟）：文件数据元（例如权限等）最后一次修改时间。

搜索最近七天内被访问过的所有文件

```shell
find . -type f -atime -7
```

搜索恰好在七天前被访问过的所有文件

```shell
find . -type f -atime 7
```

搜索超过七天内被访问过的所有文件

```shell
find . -type f -atime +7
```

搜索访问时间超过10分钟的所有文件

```shell
find . -type f -amin +10
```

找出比file.log修改时间更长的所有文件

```shell
find . -type f -newer file.log
```

#### 根据文件大小进行匹配

```shell
find . -type f -size 文件大小单元
```

文件大小单元：

*    **b**  —— 块（512字节）
*    **c**  —— 字节
*    **w**  —— 字（2字节）
*    **k**  —— 千字节
*    **M**  —— 兆字节
*    **G**  —— 吉字节

搜索大于10KB的文件

```shell
find . -type f -size +10k
```

搜索小于10KB的文件

```shell
find . -type f -size -10k
```

搜索等于10KB的文件

```shell
find . -type f -size 10k
```

#### 删除匹配文件

删除当前目录下所有.txt文件

```shell
find . -type f -name "*.txt" -delete
```

#### 根据文件权限/所有权进行匹配

当前目录下搜索出权限为777的文件

```shell
find . -type f -perm 777
```

找出当前目录下权限不是644的php文件

```shell
find . -type f -name "*.php" ! -perm 644
```

找出当前目录用户tom拥有的所有文件

```shell
find . -type f -user tom
```

找出当前目录用户组sunk拥有的所有文件

```shell
find . -type f -group sunk
```

#### 借助`-exec`选项与其他命令结合使用

找出当前目录下所有root的文件，并把所有权更改为用户tom

```shell
find .-type f -user root -exec chown tom {} \;
```

上例中， **{}**  用于与 **-exec** 选项结合使用来匹配所有文件，然后会被替换为相应的文件名。

找出自己家目录下所有的.txt文件并删除

```shell
find $HOME/. -name "*.txt" -ok rm {} \;
```

上例中， **-ok** 和 **-exec** 行为一样，不过它会给出提示，是否执行相应的操作。

查找当前目录下所有.txt文件并把他们拼接起来写入到all.txt文件中

```shell
find . -type f -name "*.txt" -exec cat {} \;> /all.txt
```

将30天前的.log文件移动到old目录中

```shell
find . -type f -mtime +30 -name "*.log" -exec cp {} old \;
```

找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来

```shell
find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;
```

因为单行命令中-exec参数中无法使用多个命令，以下方法可以实现在-exec之后接受多条命令

```shell
-exec ./text.sh {} \;
```

#### 搜索但跳过指定的目录

查找当前目录或者子目录下所有.txt文件，但是跳过子目录sk

```shell
find . -path "./sk" -prune -o -name "*.txt" -print
```

> :warning: ./sk 不能写成 ./sk/ ，否则没有作用。

忽略两个目录

```shell
find . \( -path ./sk -o  -path ./st \) -prune -o -name "*.txt" -print
```

> :warning: 如果写相对路径必须加上`./`

#### find其他技巧收集

要列出所有长度为零的文件

```shell
find . -empty
```

#### 其它实例

```shell
find ~ -name '*jpg' # 主目录中找到所有的 jpg 文件。 -name 参数允许你将结果限制为与给定模式匹配的文件。
find ~ -iname '*jpg' # -iname 就像 -name，但是不区分大小写
find ~ ( -iname 'jpeg' -o -iname 'jpg' ) # 一些图片可能是 .jpeg 扩展名。幸运的是，我们可以将模式用“或”（表示为 -o）来组合。
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f # 如果你有一些以 jpg 结尾的目录呢？ （为什么你要命名一个 bucketofjpg 而不是 pictures 的目录就超出了本文的范围。）我们使用 -type 参数修改我们的命令来查找文件。
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type d # 也许你想找到那些命名奇怪的目录，以便稍后重命名它们
```

最近拍了很多照片，所以让我们把它缩小到上周更改的文件

```shell
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f -mtime -7
```

你可以根据文件状态更改时间 （ctime）、修改时间 （mtime） 或访问时间 （atime） 来执行时间过滤。 这些是在几天内，所以如果你想要更细粒度的控制，你可以表示为在几分钟内（分别是 cmin、mmin 和 amin）。 除非你确切地知道你想要的时间，否则你可能会在 + （大于）或 - （小于）的后面加上数字。

但也许你不关心你的照片。也许你的磁盘空间不够用，所以你想在 log 目录下找到所有巨大的（让我们定义为“大于 1GB”）文件：

```shell
find /var/log -size +1G
```

或者，也许你想在 /data 中找到 bcotton 拥有的所有文件：

```shell
find /data -owner bcotton
```

你还可以根据权限查找文件。也许你想在你的主目录中找到对所有人可读的文件，以确保你不会过度分享。

```shell
find ~ -perm -o=r
```

删除 mac 下自动生成的文件

```shell
find ./ -name '__MACOSX' -depth -exec rm -rf {} \;
```

统计代码行数

```shell
find . -name "*.java"|xargs cat|grep -v ^$|wc -l # 代码行数统计, 排除空行
```



