艺考网
全国站

Linux小技巧:find命令使用详解,看完你会有收获

xunaa
2024-10-05 10:38:19
编辑说
Linux命令中,find是一个比较复杂且难用的命令。在使用这个命令搜索文件的时候,我经常发现我找到了一些可以使用的例子,但是如果稍微改变一下条件,就找不到我想要的结果了。
下面

Linux命令中,find是一个比较复杂且难用的命令。在使用这个命令搜索文件的时候,我经常发现我找到了一些可以使用的例子,但是如果稍微改变一下条件,就找不到我想要的结果了。

下面将通过一些例子来说明使用find命令时的要点和注意事项,并解释清楚为什么每个条件都可以或不可以。

具体包括以下内容:

find 命令格式介绍查找指定目录下的所有文件指定搜索时忽略一个或多个目录详细说明find 。 -path ./tests -and -prune -o -print 命令各参数含义忽略多个目录匹配特定Pattern 文件名匹配单个后缀名匹配多个后缀名重新格式化要打印的文件名信息使用正则表达式进行匹配完整路径匹配特定类型文件的文件名

find 命令格式简介

要使用命令,首先要了解命令的格式,知道要提供哪些参数以及它们的作用是什么。

查看man find对该命令的描述如下:

find - 在目录层次结构中搜索文件。find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path.] [表达式]GNU find 搜索以每个目录为根的目录树根据优先级规则,通过从左到右计算给定表达式来给定文件名,直到知道结果(左侧对于and 运算为false,对于or 为true),此时find 移动到下一个文件名。-H、-L 和-P 选项控制符号链接的处理。后面的命令行参数被视为要检查的文件或目录的名称,直到第一个以'-' 开头的参数,或参数'(' 或'!'。如果没有给出路径,则当前路径如果没有给出表达式,则使用表达式-print (但无论如何,您可能应该考虑使用-print0 )该表达式由选项组成(影响整体操作而不是特定文件的处理)。并且始终返回true),测试(返回true 或false 值)和操作(具有副作用并返回true 或false 值),全部由运算符-and 分隔,其中省略了运算符。表达式不包含除-prune 之外的任何操作, -print 对表达式为true 的所有文件执行即find 命令的作用它在目录层次结构下搜索文件,默认情况下会递归搜索。对于找到的每个文件名(目录名也属于文件名),依次判断以下表达式来决定是否打印搜索到的文件。文件名,或执行其他操作。

注意:依次计算每个搜索到的文件名的表达式非常关键。 find 命令会将每个搜索到的文件名作为参数传递给后续表达式进行评估,以决定如何处理它。对于这个文件,如果某个文件的表达式求值为false,则会继续求下一个文件,除非主动执行结束操作。

明白了这一点,就清楚为什么有的文件名会被打印而有的文件名不会被打印了,因为它们本身是没有关联的。

下面详细解释find命令格式各部分的含义:

[-H] [-L] [-P] [-D debugopts] [-Olevel] 这部分是命令选项,很少使用,这里不再解释。 [path.] 该参数指定要搜索的目录。您可以同时提供多个目录名称,并用空格分隔。如果不提供该参数,则默认搜索当前目录及其子目录。您还可以提供文件名,该文件将仅在当前目录中搜索,而不会在子目录中搜索。 [表达式] 该参数指定计算表达式。可以提供多个表达式。不同的表达式必须用运算符运算符分隔。如果表达式之间没有提供运算符,则默认使用-and 运算符。表达式分为三种类型:选项、测试和操作。如果未提供此参数,则默认使用-print 表达式,打印出给定的文件名。参考上面的说明,表达式参数必须以'-'、'(' 或'!' 开头,以区分前面的目录参数。注意,在bash 中,使用'\(' 来转义'(' 。有关说明find命令,还可以查看GNU find在线帮助手册https://www.gnu.org/software/findutils/manual/html_mono/find.html,这里的说明比man find更详细,并提供了很多示例可供参考。

在Linux 中,目录也是文件。 find 搜索时,会将目录视为文件。它搜索并处理目录名,而不仅仅是文件名。

在下面的说明中,除非另有说明,文件名包括目录名。

查找指定目录下的所有文件

使用find 命令的最简单方法是直接执行该命令,无需提供任何参数。默认情况下,它会搜索当前目录及其子目录中的所有文件,并打印出所有文件名。

具体例子如下:

$ lsMakefile.am src tests$ find./src./src/main.c./tests./tests/bre.tests./Makefile.am 可以看到在shell当前工作目录下执行find命令不提供任何参数将会打印出当前目录及其子目录下的所有文件名,包括目录名。

您可以通过在find 命令后提供目录名称来指定要搜索的目录:

$ find ./src./src/main.c./tests./tests/bre.tests./Makefile.am$ 查找srcsrcsrc/main.c$ 在Linux 上查找src testsrcsrc/main.cteststests/bre.tests下面,点“.”对应当前目录,所以find .就是查找当前目录下的所有文件。当未提供目录参数时,“.”默认使用参数。

find src 命令指定仅搜索src 目录中的所有文件。

find src test命令指定搜索src和tests目录中的所有文件。可以同时提供多个目录名称来指定对这些目录的搜索。

find src tests 命令也可以写成find ./src ./tests。

如果在find 命令后提供文件名,则仅在当前目录中搜索该文件,而不会在子目录中搜索:

$ find Makefile.amMakefile.am$ find main.cfind: `main.c': No such file or directory 结合上面打印的文件信息,可以看到当前目录下有一个Makefile.am文件。您可以使用find Makefile.am 命令找到它。这个文件不会报错。

main.c 文件位于src 子目录中。执行find main.c命令时报错,提示找不到文件。它不会进入src子目录进行搜索。

注意:前面提到,搜索条件需要以‘-’、‘(’或‘!’开头,在遇到任何以这些字符开头的参数之前,前面的参数将被视为目录参数,指定搜索时有多个目录,直接在find命令后面写上这些目录的路径,并用空格分隔即可,不需要添加-o、-path等选项,可能会导致异常。

刚接触find 命令时,常见的误解之一是需要使用-o 选项来指定要搜索的多个目录。

例如,认为find src -otests会同时搜索src和tests这两个目录。这是一种不正确的写法,执行时会报错:

$ find src -otestsfind: paths must before expression:tests 可以看到执行错误报告必须在表达式参数之前提供目录路径参数。以- 开头的-o 参数将被视为表达式参数。它和它后面的所有参数将被视为表达式参数。此后提供的目录名称将不被视为要搜索的目录。

一些表达式参数后面可以提供目录名称,但这些目录名称并不是用来指定搜索目录中的文件,而是有其他含义。

还有一个误区是,执行find src -otests命令报错后,仍然不知道错误在哪里。顾名思义,增加了-path选项,误写为find src -o -pathtests,或者find src -path -otests。这两个命令都会报错,你自己测试一下就知道了。

虽然写find src -pathtests不会报错,但是不会打印出src和tests目录下的文件名。

-path参数的用法稍后会详细解释。

查找时指定忽略一个或多个目录

基于上例的目录结构,如果想查找当前目录下的文件并忽略tests目录,可以执行以下命令:

$ 查找. -path ./tests -prune -o -print./src./src/main.c./Makefile.am 可以看到打印的文件名不包含tests目录名及其下的文件名。

但如果将上面-path后面的./tests改为tests,仍然会搜索tests目录下的文件:

$ 查找. -path tests -prune -o -print./src./src/main.c./tests./tests/bre.tests./Makefile.am 这个结果很奇怪。我想在搜索时忽略测试目录。写成-path ./tests可以忽略,写成-path test则不能忽略。

这是使用find 命令的-path 参数时的常见错误。别人的例子可以,但是自己写就不行了。这需要理解-path参数的含义才能正确使用它。

正如前面提到的,不同的表达式必须用运算符分隔。如果未提供运算符,则默认使用-and 运算符。

所以find 的完整格式。 -path ./tests -prune -o -print 命令实际上是find 。 -path ./tests -and -prune -o -print。

下面详细解释这个完整命令格式的各个参数,以便了解其工作原理以及为什么写成-path ./tests 时可以忽略而写成-path test 时不能忽略。

-path pattern

这是一个测试类型表达式。 GNU find在线帮助手册对该表达式的解释如下:

Test: -路径模式

如果整个文件名(从在其下找到该文件的命令行参数开始)与shell 模式匹配,则为True。

要忽略整个目录树,请使用“-prune”而不是检查树中的每个文件。

find 使用的“整个文件名”以命令行上指定的起点开始,并且不会转换为绝对路径名。

也就是说,当find 命令找到的文件名与给定模式完全匹配时,此表达式返回true。

这里最关键的一点是要完全匹配find命令找到的名称,而不是部分匹配,也不是与文件的绝对路径名匹配。

具体例子如下:

$ 查找. -路径./tests./tests$ 查找. -路径测试$查找。 -path ./tests/$ findteststeststests/bre.tests$ findtests -pathteststests$findtests -path./tests 你可以看到,find。 -path ./tests 命令打印./tests 目录名称,但find . -path测试命令没有打印任何内容。

查看find 打印的信息。上面的命令,可以看到该命令打印的测试目录名称为./tests。 -path参数需要完全匹配才能返回true,所以根据打印结果,必须写成-path ./tests 才会返回true。

前面发布的man find 说明提到,当除了-prune 表达式之外没有提供其他动作类型表达式时,对于所有返回true 的文件名将默认执行-print 表达式,并打印文件名。

因此,打印结果中只有匹配的./tests目录名称。不完全匹配./tests 的文件名将返回false 并且不会打印。

由于find 打印的目录名称。命令后面没有/字符, find 。 -path ./tests/无法匹配任何文件名,并且不打印任何信息。

同样,如果执行findtests命令并且打印的tests目录名为tests,那么findtests-pathtests命令可以完全匹配tests模式并打印出目录名。

但是, find test -path ./tests 无法匹配,因此不会打印。

即根据传入的目录参数的不同,find打印的目录名不同,-path后面要提供的目录名也不同。

一般来说,-path后面的目录名需要与find命令打印的目录名完全匹配,而不是部分匹配。如果不确定find命令打印的目录名是什么,可以在不加-path参数的情况下执行find命令,看看打印的文件名是什么,然后在-path参数后面写上对应的文件名。

-path后面的模式pattern可以使用通配符来匹配特定模式的文件名。常见的通配符是*,用于匹配零个或多个字符。

使用find时有一些需要注意的地方。示例如下:

$ 查找. -路径*测试*$查找。 -path ./test*./tests$ 查找. -path \*test\*./tests./tests/bre.tests$ 查找. -path '*test*' ./tests./tests/bre.tests 你可以看到find 。 -path *test* 不打印任何内容,并且*test* 与名称./tests 不匹配。

原因是这里的*通配符经过bash处理,通过文件名扩展得到当前目录下的子目录名或者文件名,但是目录名前面没有添加./。

即找到. -path *test* 这里相当于find 。 -path 测试,如前所述,这是不匹配的。

寻找。 -path ./test* 可以打印出匹配的目录名。 bash 扩展后,该命令相当于find 。 -路径./测试。

发现。 -path \*test\* 命令不仅匹配./tests目录,还匹配该目录下的./tests/bre.tests文件。

这里,\* 用于转义*。对于bash来说,它不再是通配符,也不经过扩展处理。而是将*字符传递给find命令,find命令本身进行通配符处理,这样可以匹配更多的字符。文档。

这就涉及到bash和find in *通配符扩展的区别了。 bash在文件名中展开*时,遇到斜杠字符/就会停止,不会展开到目录下的文件名。

但find并不将/视为特殊字符,会继续扩展到目录下的文件名。

查看GNU find 在线帮助手册https://www.gnu.org/software/findutils/manual/html_mono/find.html#Shell-Pattern-Matching 的说明如下:

斜杠字符在find 和locate 所做的shell 模式匹配中没有特殊意义,这与shell 中的通配符不匹配斜杠字符不同。

find 的打印结果。 -path '*test*' 命令与find 相同。 -路径\*测试\*。

原因是bash不把双引号内的*当作通配符,而会通过这个字符去find,而find会处理通配符扩展。

如果不想使用\* 进行转义,可以将模式字符串括在双引号中。

注意:虽然-path 表达式的名称似乎对应于目录路径,但它也可用于匹配文件名,而不仅仅是目录。

man find 中提到有一个-wholename 表达式相当于-path 表达式,但只有GNU find 命令支持-wholename 表达式,其他版本的find 命令不支持该表达式。在名称方面,-wholename 表达式更准确地表达了与文件名完全匹配的需要。

-and

这是接线员。 GNU find在线帮助手册对该操作符的解释如下:

表达式1 表达式2

表达式1 -a 表达式2

expr1 - 和expr2

和;如果expr1 为false,则不会计算expr2。

正如您所看到的,-and 运算符有三种不同的写法,它们都是等效的。

find 命令的运算符将多个表达式组合在一起形成一个新的组合表达式。组合表达式还将有其自己的返回值。

使用-and 运算符组合的表达式要求两个表达式都为true,组合表达式才为true。

当左边的expr1 表达式为false 时,不再计算右边的expr2 表达式,并且组合表达式返回false。

发现。上例中的-pathtests 命令没有打印任何内容,这与-and 运算符的特性有关。

由于该命令没有提供action类型表达式,因此默认添加-print 表达式,即find 。 -路径测试-打印。

由于-path test 和-print 之间没有提供运算符,因此默认添加-and 运算符,即find 。 -路径测试-和-打印。

Linux小技巧:find命令使用详解,看完你会有收获

find 搜索到的所有文件名。命令与-path 测试模式不匹配并且全部返回false。根据-and运算符的特性,如果不执行-print表达式,则不会打印文件名。

-prune

这是一个动作类型表达式。 GNU find在线帮助手册对该表达式的解释如下:

Action:-修剪

如果该文件是目录,则不要进入该目录。结果是真的。

例如,跳过目录src/emacs及其下的所有文件和目录,并打印其他文件的名称found:

寻找。 -全名'./src/emacs' -prune -o -print

上面的命令不会在其结果列表中打印./src/emacs。然而,这并不是由于“-prune”操作的影响(这只会阻止进一步下降,并不能确保我们忽略该项目)。

相反,这种效果是由于使用“-o”造成的。由于“or”条件的左侧对于./src/emacs 已成功,因此根本没有必要针对该特定文件评估右侧('- print')。

这里给出的例子与我们现在讨论的例子类似。还解释了为什么搜索时可以忽略目录,供参考。

如前所述,find 命令会将搜索到的每个文件名作为参数传递给后续表达式进行求值。

如果传递给-prune 表达式的文件名是目录,则不会搜索该目录。

该表达式的返回值始终为true。

具体例子如下:

$ 查找. -path \*test\* -prune./tests$ 查找. -path \*test\* -o -prune。如上例所述,查找. -path \*test\* 将匹配./tests 目录以及该目录中的./tests/bre.tests 文件。

发现。 -path \*test\* -prune 这里只匹配./tests目录。它不会搜索该目录中的文件,因为它受到-prune 表达式的影响。

根据前面的解释,找到. -path \*test\* -prune 相当于find 。 -path \*test\* -and -prune -and 打印。

对于与\*test\* 模式不匹配的文件名,-path \*test\* 表达式返回false,不执行进一步处理,并且不打印不匹配的文件名。

对于与\*test\* 模式匹配的文件名,-path \*test\* 表达式返回true,并且处理将继续,直到遇到-prune 表达式。该表达式始终返回true,并继续处理-print 表达式以打印出目录名称。

由于-prune表达式指定不进入对应的目录,所以找不到该目录下的文件,也找不到./tests/。

bre.tests 文件。

-o

这是一个 operator 操作符,GNU find 在线帮助手册对该操作符的说明如下: expr1 -o expr2 expr1 -or expr2 Or; expr2 is not evaluated if expr1 is true. 使用 -o 操作符组合的表达式要求两个表达式都是 false,该组合表达式才是 false。 左边的 expr1 表达式为 true 时,不再评估右边的 expr2 表达式,该组合表达式会返回 true。 前面提到, find . -path tests 命令什么都没有打印,跟使用了 -and 操作符有关,如果改成 -o 操作符,结果就会不一样。 具体举例如下: $ find . -path tests -o -print../src./src/main.c./tests./tests/bre.tests./Makefile.am$ find . -path ./tests -o -print../src./src/main.c./tests/bre.tests./Makefile.am可以看到,find . -path tests -o -print 命令打印了当前目录下的所有文件名。 由于 -path tests 什么都匹配不到,都返回 false,基于 -o 操作符的特性,全都执行后面的 -print 表达式,打印所有文件名。 这个结果跟 find . -path tests 命令完全相反。 类似的,find . -path ./tests -o -print 命令的打印结果跟 find . -path ./tests 命令也相反。 前者的打印结果不包含 ./tests 目录名,后者的打印结果只包含 ./tests 目录名。 对于匹配 -path ./tests 模式的目录名,该表达式返回 true,基于 -o 操作符的特性,不往下执行 -print 表达式,所以不打印该目录名。

-print

这是一个 action 类型表达式,GNU find 在线帮助手册对该表达式的说明如下: Action: -print True; print the entire file name on the standard output, followed by a newline. 前面例子已经说明过 -print 表达式的作用,它会打印传递下来的完整文件路径名,会自动添加换行符。 如果没有提供除了 -prune 之外的其他 action 类型表达式,find 默认会加上 -print 表达式,并用 -and 来连接前面的表达式。 这个行为可能会带来一些误解,认为 find 命令总是会打印搜索到、或者匹配到的文件名,但有时候搜索到、或者匹配到的文件名反而不打印。 例如上面 find . -path ./tests -o -print 的例子。 要消除这个误解,就一定要清楚地认识到,find 命令想要打印文件名,就必须执行到 -print 表达式、或者其他可以打印文件名的表达式。 即,要执行可以打印文件名的表达式才会打印文件名,否则不会打印。 至于是匹配特定模式的文件名会打印,还是不匹配特定模式的文件名才会打印,取决于各个表达式、包括操作符组合表达式的判断结果,看是否会执行到可以打印文件名的表达式。

总结

结合上面的说明,对 find . -path ./tests -and -prune -o -print 命令在查找时能够忽略 ./tests 目录底下文件的原因总结如下: find . 指定查找当前目录、及其子目录下的所有文件,每查找到一个文件名,就把这个文件名传递到后面的表达式进行评估,进行相应处理。-path ./tests 指定传递下来的文件名要完全匹配 ./tests 这个字符串。对于不匹配的文件名,该表达式返回 false,那么 -path ./tests -and -prune 这个组合表达式会返回 false,且没有评估后面的 -prune 表达式。由于 -and 操作符优先级高于 -o 操作符,该组合表达式再跟后面的 -o -print 形成新的组合表达式,它返回 false,会往下执行 -print 表达式,从而打印出来不匹配的文件名。对于匹配 -path ./tests 模式的目录名,该表达式返回 true,-path ./tests -and -prune 组合表达式会评估后面的 -prune 表达式,指定不进入匹配的目录名查找底下的文件,这个例子里面就是不进入 ./tests 目录,所以查找时会忽略该目录底下的文件,但还是会查找到 ./tests 目录名自身。对于 ./tests 这个目录名,由于 -prune 返回 true,-path ./tests -and -prune 组合表达式会返回 true,基于 -o 操作符的特性,不执行后面的 -print 表达式,所以没有打印这个目录名。最后的 -o -print 是必要的,如果不加这两个参数,将不会打印不匹配 ./tests 模式的文件名。基于这几条分析,这个命令最终打印的结果里面,即不包含 ./tests 这个目录名,也不包含它底下的文件名。总的来说,使用 find 命令查找时,如果要忽略一个目录,可以用类似 find . -path ./tests -prune -o -print 这样的写法。 理解了上面对该命令的说明后,想要忽略其他模式的目录,应该就比较容易了。

忽略多个目录的写法

如果想要忽略多个目录,要使用 -o 操作符把多个 -path pattern 表达式组合起来。 基于上面例子的目录结构,举例如下: $ find . \( -path ./tests -o -path ./src \) -prune -o -print../Makefile.am可以看到,find . \( -path ./tests -o -path ./src \) -prune -o -print 命令打印的查找结果里面,没有 ./src、./tests 这两个目录、及其底下文件,也就是忽略了这两个目录。 基于 -o 操作符的特性,-path ./tests -o -path ./src 组合表达式在不匹配 ./tests 模式时,会再尝试匹配 ./src 模式,两个模式都不匹配,才会返回 false。 由于 -and 操作符优先级高于 -o 操作符,所以要用小括号 () 把 -path ./tests -o -path ./src 组合表达式括起来,形成一个独立的表达式,再跟后面的 -prune 组合成新的表达式。 小括号在 bash 中有特殊含义,所以要加 \ 转义字符,写成 \(,避免 bash 对小括号进行特殊处理。 注意:在 \( 和 \) 前后要用空格隔开,这两个是单独的操作符,如果不加空格,会组合成其他名称。 其他表达式的含义和作用可以参考前面例子的说明。 如果能够基于这个命令的各个表达式、各个操作符的作用,推导出打印结果,就基本理解 find 命令的工作原理了。

匹配特定模式的文件名

上面说明的 -path pattern 表达式要求完全匹配整个目录路径,如果想要只匹配文件名,不包含目录路径部分,可以使用 -name pattern 表达式。 这是一个 test 类型表达式,GNU find 在线帮助手册对该表达式的说明如下: Test: -name pattern

Linux小技巧:find命令使用详解,看完你会有收获

True if the base of the file name (the path with the leading directories removed) matches shell pattern pattern. As an example, to find Texinfo source files in /usr/local/doc: find /usr/local/doc -name '*.texi' Notice that the wildcard must be enclosed in quotes in order to protect it from expansion by the shell. 如这个帮助说明所举的例子,一般常用这个表达式来匹配特定后缀名的文件。具体举例如下。

匹配单个后缀名

下面是匹配单个后缀名的例子: $ find . -name '*.c'./src/main.c可以看到,find . -name '*.c' 命令打印出所有后缀名为 .c 的文件名。 注意 *.c 要用引号括起来,避免 bash 当 * 号当成通配符处理。 该命令相当于 find . -name '*.c' -and -print,只有 -name '*.c' 表达式返回为 true 的文件名才会执行到 -print 表达式,打印出该文件名。 注意:使用 -name pattern 表达式并不表示只查找符合 pattern 模式的文件,find 命令还是会查找出所给目录的所有文件,并把每个文件名依次传给后面的表达式进行评估,只有符合 -name pattern 表达式的文件名才会返回 true,才会被打印出来。 不符合这个表达式的文件也会被查找到,只是没有打印出来而已。

匹配多个后缀名

下面是匹配多个后缀名的例子: $ find . -name '*.c' -o -name '*.am'./src/main.c./Makefile.am$ find . \( -name '*.c' -o -name '*.am' \) -and -print./src/main.c./Makefile.am$ find . -name '*.c' -o -name '*.am' -and -print./Makefile.am可以看到,find . -name '*.c' -o -name '*.am' 命令打印出所有后缀名为 .c 和 .am 的文件名。 该命令相当于 find . \( -name '*.c' -o -name '*.am' \) -and -print,而不是相当于 find . -name '*.c' -o -name '*.am' -and -print,后者只能打印出后缀名为 .am 的文件名。 前面也有说明,find 命令会对所有返回为 true 的文件名默认执行 -print 表达式,这个返回为 true 是手动提供的整个表达式的判断结果。 也就是说手动提供的整个表达式应该会用小括号括起来,组成独立的表达式,再跟默认添加的 -and -print 表达式组合成新的表达式,避免直接加上 -and -print 后,会受到操作符优先级的影响,打印结果可能不符合预期。

重新格式化要打印的文件名信息

除了使用 -print 表达式打印文件名之外,也可以使用 -printf 表达式格式化要打印的文件名信息。 这是一个 action 类型表达式,GNU find 在线帮助手册对该表达式的说明如下: Action: -printf format True; print format on the standard output, interpreting ‘\’ escapes and ‘%’ directives. Field widths and precisions can be specified as with the printf C function. Unlike ‘-print’, ‘-printf’ does not add a newline at the end of the string. If you want a newline at the end of the string, add a ‘\n’. 即,-printf 表达式使用类似于C语言 printf 函数的写法来格式化要打印的信息,支持的一些格式如下: %pFile’s name.这个格式包含完整路径的文件名。%fFile’s name with any leading directories removed (only the last element).这个格式只包含文件名,会去掉目录路径部分。注意:-printf 是 action 类型表达式,前面提到,如果提供除了 -prune 之外的 action 类型表达式,将不会自动添加 -print 表达式。 加了 -printf 表达式将由该表达式来决定打印的文件信息。 使用 -printf 表达式的例子如下: $ find . \( -name '*.c' -o -name '*.am' \) -printf "%f \t%p\n"main.c ./src/main.cMakefile.am ./Makefile.am可以看到,所给 find 命令打印出指定后缀的文件名本身、以及完整路径的文件名。 -name '*.c' -o -name '*.am' 表达式需要用小括号括起来,组成独立的表达式。 如果不加小括号,由于 -and 操作符优先级高于 -o 操作符,-name '*.am' 实际上是跟 -printf 表达式组合,后缀名为 .c 的文件名无法执行到 -printf 表达式,将不会打印这些文件名。 由于 -printf 表达式不会在末尾自动加上换行符,想要换行的话,需要在格式字符串里面加上 ‘\n’ 换行符。

使用正则表达式匹配完整路径文件名

在 find 命令里面,-path pattern 表达式和 -name pattern 表达式都是使用通配符来匹配模式,如果想要用正则表达式进行匹配,可以使用 -regex expr 表达式。 这是 test 类型表达式,GNU find 在线帮助手册对该表达式的说明如下: -regex expr True if the entire file name matches regular expression expr. This is a match on the whole path, not a search. As for ‘-path’, the candidate file name never ends with a slash, so regular expressions which only match something that ends in slash will always fail. 即,-regex expr 表达式用正则表达式匹配完整路径的文件名,包含目录路径部分。 用正则表达式匹配后缀名为 .c 文件的例子如下: $ find . -regex '.*\.c'./src/main.c$ find . -regex '.*c'./src./src/main.c可以看到,find . -regex '.*\.c' 命令只打印出后缀名为 .c 的文件名。 而 find . -regex '.*c' 命令除了打印后缀名为 .c 的文件名,还打印了其他的文件名,这个命令的正则表达式不够精确,少了关键的 \. 来转义匹配点号 . 字符。 在 .*\.c 这个正则表达式中,最前面的 . 表示匹配任意单个字符,* 表示匹配零个或连续多个前面的字符,\. 通过转义来表示 . 字符自身,c 表示字符 c 自身,组合起来就是匹配后缀名为 .c 的字符串。 而 .*c 这个正则表达式匹配最后一个字符为 c 的字符串,不管在字符 c 前面是否有 . 字符,这个不符合后缀名的要求。 下面例子用正则表达式来匹配多个后缀名: $ find . -regex '.*\.\(c\|am\)'./src/main.c./Makefile.am这个例子同时匹配后缀名为 .c 和 .am 的文件名。 在正则表达式中,(a|b) 表示匹配 a 或者匹配 b。上面的 \(c\|am\) 经过转义后,也就是 (c|am),用于匹配 c 或者 am,这样就比较好理解,不要被转义字符吓到了。

匹配特定类型的文件

find 命令可以用 -type c 表达式来指定匹配这些类型的文件。 这是一个 test 类型表达式,GNU find 在线帮助手册对该表达式的说明如下: Test: -type c True if the file is of type c: d: directory f: regular file l: symbolic link

用户评论

志平

终于找到一个解释了 find 命令用法的!太棒了

    有5位网友表示赞同!

一生荒唐

一直想学习一下 Linux 的 find 命令,这篇文章正好能帮我入门

    有20位网友表示赞同!

最怕挣扎

这个标题很有吸引力,我决定看看有没有什么新知识可以学到

    有20位网友表示赞同!

此刻不是了i

我的Linux基础不太好,看完这篇文章应该就能更了解find命令的使用方法了

    有13位网友表示赞同!

封心锁爱

想在 Linux 系统中寻找文件时用 find 命令,这篇文章应该能帮上忙

    有5位网友表示赞同!

花开丶若相惜

收获良多!以前没怎么用过 find 命令,这篇讲解非常详细。

    有13位网友表示赞同!

堕落爱人!

看标题就知道是干货满满的分享了,期待学习新的 Linux 技巧

    有6位网友表示赞同!

ok绷遮不住我颓废的伤あ

学习 Linux 的朋友们,这篇文章值得一看!

    有14位网友表示赞同!

开心的笨小孩

-a -name 这几个参数用法真详细,受益匪浅。

    有20位网友表示赞同!

歆久

找文件神器 find 命令,终于明白怎么用它了!

    有19位网友表示赞同!

半梦半醒半疯癫

这篇讲解把 find 命令的各种用法都总结得很清晰,太棒啦!

    有19位网友表示赞同!

看我发功喷飞你

-type 文件类型筛选,我一直不知道这种功能,真是太有用!感谢分享!

    有17位网友表示赞同!

有阳光还感觉冷

看完这篇文章,我对 find 命令的使用方法有了更深入的了解。

    有5位网友表示赞同!

柠栀

Linux 系统常用工具,一定要掌握 find 命令!

    有12位网友表示赞同!

回到你身边

这篇教程讲解的很详细,比我之前看的其他资料要清晰很多。

    有9位网友表示赞同!

相知相惜

find 命令真强大!学习之后感觉 Linux 操作能力提升了好多

    有10位网友表示赞同!

执笔画眉

以前总是手忙脚乱找文件,现在有了 find 命令,真是太方便啦!

    有6位网友表示赞同!

寂莫

一定要看看这篇文章,里面有很多实用的 Linux 技巧。

    有15位网友表示赞同!

免责声明
本站所有收录的学校、专业及发布的图片、内容,均收集整理自互联网,仅用于信息展示,不作为择校或选择专业的建议,若有侵权请联系删除!

大家都在看

Linux小技巧:find命令使用详解,看完你会有收获

Linux小技巧:find命令使用详解,看完你会有收获

Linux命令中,find是一个比较复杂且难用的命令。在使用这个命令搜索文件的时候,我经常发现我找到了一些可以使用的例子,但是如果稍微改变一下条件,就找不到我想要的结果了。 下面
2024-10-05
英语中find/found的用法及区别

英语中find/found的用法及区别

find/found的用法和区别 英语语法词性动词形态 1. 当found为动词原型时,解释为:create,后接名词 例如:他几年前创办了这所学校。 2. Found是过去时态。当用作过去分词时,原型是f
2024-10-05
几个、几个、一点、一点的区别

几个、几个、一点、一点的区别

冰箱里鸡蛋不多了,他就去超市买了一些。 她的朋友很少,而且通常都不太快乐。她的朋友很少,而且通常都不太快乐。 我为几个亲密的朋友举办了一次晚宴。我为几个亲密的朋友举办了
2024-10-05
在一篇文章中阅读它!一点点和一点点、一点点和一点点有什么区别以及如何使用它们?用途介绍

在一篇文章中阅读它!一点点和一点点、一点点和一点点有什么区别以及如何使用它们?用途介绍

Little: 用在不可数名词前,表示“很少,几乎没有”。通常用在否定句或疑问句中,表达不满意的情况或询问数量。例如:“还有牛奶吗?” 'Just a little.'a little: 也用在不可数名
2024-10-05
初中常用词汇分析,初中易混淆词汇分析:几个,几个,一点点,一点点

初中常用词汇分析,初中易混淆词汇分析:几个,几个,一点点,一点点

Few, a Few, Little, Little的区别及用法: 一些,一点点是积极意义,一些,一点点。很少和很少表达负面含义,没有和几乎没有。 1. Few/a Few 用于修饰可数名词。 1. Few表示负面
2024-10-05
英语语法few\a和little\a little的区别

英语语法few\a和little\a little的区别

几个\几个 Few 和Few 后面跟可数名词的复数形式。 a Few表示数量很少或几乎不存在,强调“很少”,有否定意义; a few表示数量虽少,但仍然存在,强调“有”,有积极意义: 很少有人
2024-10-05
几、几、一点、一点的区别:史上最详细解释

几、几、一点、一点的区别:史上最详细解释

1、few的意思是“很少,不多”,有消极的意思。它常与短语of连用,在句子中充当主语、宾语等。当few用作形容词时,意思是“很少”。用在复数可数名词之前,在句子中用作定语,表达否定
2024-10-05
一张图教你掌握比较级和最高级的“各种变化规则”

一张图教你掌握比较级和最高级的“各种变化规则”

嘿伙计们!这是詹妮弗。 今天是5分钟英语语法初级语法-形容词(第1部分) 我们主要研究形容词的位置(单/多个)和形容词(副词)的比较级最高级变化。 视频讲解 视频加载中. 思维导图 下
2024-10-05
小学英语语法、形容词比较级形式

小学英语语法、形容词比较级形式

比较: 1.形容词的比较级形式 1、形容词比较级在句子中的使用:要比较两个事物或两个人,可以使用比较级形式,后面通常加“比”一词。 比较句结构通常是: What+动词be(am,is,are)+形
2024-10-05
小学英语:形容词比较级最高级变化规律和形容词不规则变化

小学英语:形容词比较级最高级变化规律和形容词不规则变化

形容词用来修饰名词或代词,以表达人或事物的性质、状态和特征。它的位置通常放在被修饰的名词之前,或动词be和look、feel、taste、sound和get之后。 2.形容词的比较级和最高级
2024-10-05