Linux技巧:find 命令简单入门介绍和问题点解析


Linux技巧:find 命令简单入门介绍和问题点解析

文章插图
 
在 linux 命令中,find 是比较复杂难用的命令 。使用该命令搜索文件时,常常发现自己找了一些例子能用,但稍微改一下条件,就搜不到想要的结果 。
下面会以一些实例来说明使用 find 命令的关键要点和注意事项,解释清楚各个条件能够工作、或者不能工作的原因 。
find 命令格式要使用一个命令,首先要了解命令的格式,知道要提供什么参数、参数作用是什么 。
查看 man find 对该命令的说明如下:
  • find - search for files in a directory hierarchy.
  • find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
  • GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to the rules of precedence, until the outcome is known (the left hand side is false for and operations, true for or), at which point find moves on to the next file name.
  • The -H, -L and -P options control the treatment of symbolic links. Command-line arguments following these are taken to be names of files or directories to be examined, up to the first argument that begins with ‘-’, or the argument ‘(’ or ‘!’.
  • If no paths are given, the current directory is used. If no expression is given, the expression -print is used (but you should probably consider using -print0 instead, anyway).
  • The expression is made up of options (which affect overall operation rather than the processing of a specific file, and always return true), tests (which return a true or false value), and actions (which have side effects and return a true or false value), all separated by operators. -and is assumed where the operator is omitted.
  • If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.
即,find 命令的作用是在目录层次结构下搜索文件,默认会递归搜索所给目录的子目录,对查找到的每一个文件名(目录名也属于文件名)依次进行后面表达式的判断,来决定是否打印搜索到的文件名、或者进行其他的操作 。
注意:对每一个搜索到的文件名都依次进行表达式评估是非常关键的点,find 命令会把搜索到的每一个文件名都依次作为参数传递给后面的表达式进行评估,来决定如何处理这个文件,某个文件的表达式评估为 false,还是会继续评估下一个文件,除非主动执行了结束的操作 。
理解这一点,就会清楚为什么有些文件名会打印出来,而有些文件名不会打印出来,因为它们本身就相互不关联 。
下面具体说明 find 命令格式各个部分的含义:
  • [-H] [-L] [-P] [-D debugopts] [-Olevel] 这部分属于命令选项,比较少用到,这里不做说明 。
  • [path...] 该参数指定要查找哪个目录,可以同时提供多个目录名,用空格隔开,如果没有提供该参数,默认查找当前目录、及其子目录 。也可以提供文件名,只在当前目录下查找该文件,不会在子目录中查找 。
  • [expression] 该参数指定评估表达式,可以提供多个表达式,不同表达式之间要用 operator 操作符来分隔开,如果表达式之间没有提供操作符,默认会用 -and 操作符 。表达式有 option、test、action 三种类型 。如果不提供该参数,默认使用 -print 表达式,也就是打印出所给的文件名 。参考上面说明,表达式参数要求以 ‘-’、‘(’、或者 ‘!’开头,以便区分开前面的目录参数 。注意,在 bash 中要用 ‘(’ 来对 ‘(’ 进行转义 。
关于 find 命令的说明,也可以查看 GNU find 的在线帮助手册 https://www.gnu.org/software/findutils/manual/html_mono/find.html,这里面的说明比 man find 详细,并提供了不少例子,可供参考 。
在 Linux 中,目录也属于文件,find 在查找时,把目录也当成文件处理,会查找并处理目录名,并不是只处理文件名 。
后面在说明时,如无特别备注,所说的文件名包含了目录名 。
查找指定目录下的所有文件find 命令最简单的用法就是直接执行这个命令,不提供任何参数,默认会查找当前目录、及其子目录下的所有文件,并打印出所有文件名 。
具体举例如下:
$ lsMakefile.amsrctests$ find../src./src/main.c./tests./tests/bre.tests./Makefile.am可以看到,在 shell 的当前工作目录下执行 find 命令,不提供任何参数,会打印出当前目录、及其子目录下的所有文件名,包括目录名 。
可以在 find 命令后面提供目录名,指定要查找哪个目录:


推荐阅读