find — 查找文件

find 实用程序可用于搜索和对匹配给定一组条件的文件组执行命令。基本用法是 find path rules

为了可移植性,始终指定路径。不要依赖于 find 在未提供路径时默认为当前工作目录。

有用的规则包括

规则 效果 POSIX?
-name "blah" 仅查找名为 blah 的文件。可以使用 *? 通配符,但应像在 -name 'blah*' 中那样用引号括起来。
\! -name "blah" 仅查找未命名为 blah 的文件。
-type f 仅查找普通文件,而不是目录。
-type d 仅查找目录。
-type l 仅查找符号链接。
-user foo 仅查找属于用户 foo 的文件。最好使用命名的用户而不是数字 UID。特别是,root 在某些系统上可能不是 UID 0。
-group foo 仅查找属于组 foo 的文件。最好使用命名的组而不是数字 GID。
-maxdepth 3 仅向下深入子目录 3 级。 -maxdepth 1 将忽略指定路径的所有子目录。 否,GNU 和 BSD
-mindepth 2 在匹配发生之前,忽略前 2 个目录级别。 -mindepth 1 将处理除命令行参数之外的所有文件。 否,GNU 和 BSD
-exec foo '{}' 执行命令。 {} 被当前匹配文件的名称替换。请参阅以下示例。
-execdir foo '{}' -exec 相同,但从匹配项的基目录中运行命令。 否,GNU 和 BSD
-delete 删除匹配项。 否,GNU 和 FBSD
-print0 在输出中使用空字符而不是换行符分隔文件名。这对防止文件名中包含换行符的文件很有用。 否,GNU 和 FBSD

默认情况下,find 将用换行符分隔的文件列表回显到标准输出。它可以与一个 for 循环结合使用,用于少量文件,并且它们的名称中没有奇怪的字符和空格

for f in $(find "${S}" -type f) ; do
	einfo "Doing unholy things to ${f}"
done

以上循环可能会导致名称中包含特殊字符的文件出现问题。更好的方法是在一个 while 循环中使用带有 -print0 选项的 find(注意传递给 whileread 的选项用于更改分隔符)

while IFS="" read -d $'\0' -r f ; do
	einfo "Calling down holy vengance upon ${f}"
done < <(find "${S}" -type f -print0)

作为替代方案,您可以使用 -exec 参数。请小心转义,以确保 bash 不会吞噬特殊字符

find "${S}" -name '*.data' -exec mv '{}' "${S}/data/" \;

-exec; 字符终止(需要转义或用引号括起来)时,命令行将为每个匹配项分别构建。如果它被 + 字符终止,则命令行将通过在末尾追加每个选定文件名来构建。

以下语法在您要运行的命令接受多个参数(例如 doins)时很有用,并且在这种情况下效率更高

find "${S}" -name '*.so*' -exec doexe '{}' +

Find 还支持负匹配

find "${S}/bundled-libs" \! -name 'libbass.so' -delete

这将删除 “bundled-libs” 文件夹中的所有文件,除了 “libbass.so”。确保始终转义 ! 字符,这样它就不会被 shell 解释。

有关更多详细信息和示例,请参阅 find(1) IEEE Std 1003.1-2017-find