find 命令
find – walk a file hierarchy
在 Linux 命令中,find 是比较复杂难用的命令。
关于 find 命令的说明,也可以查看 GNU find 的在线帮助手册
在 Linux 中,目录也属于文件,find 在查找时,把目录也当成文件处理,会查找并处理目录名,并不是只处理文件名。
|
|
查找指定目录下的所有文件
|
|
|
|
|
|
在 Linux 下,点号 ‘.’ 对应当前目录,所以 find . 就是查找当前目录下的所有文件,当没有提供目录参数时,默认就是使用 ‘.’ 这个参数。
find src
命令指定只查找 src 这个目录下的所有文件。
find src tests
命令指定查找 src、tests 这两个目录下的所有文件,可以同时提供多个目录名来指定查找这些目录。
find src tests
命令也可以写为 find ./src ./tests
如果在 find 命令后面提供文件名,则只在当前目录下查找该文件,不会在子目录下查找
|
|
匹配特定模式的文件名 -name
如果想要只匹配文件名,不包含目录路径部分,可以使用 -name pattern 表达式。
|
|
匹配特定类型的文件 -type
在 Linux 中,文件类型可以分为目录 (directory)、文本文件 (regular file)、符号链接 (symbolic link)、socket,等等。
- d: directory
- f: regular file
- l: symbolic link
- s: socket
|
|
指定时间戳查找 -atime
mtime
ctime
要按指定的时间戳搜索文件,Linux 系统中的 3 个不同的时间戳:
- 访问时间戳 (atime):最后一次读取文件的时间。
- 修改时间戳 (mtime):文件内容最后一次被修改的时间。
- 更改时间戳 (ctime):上次更改文件元数据的时间(如,所有权、位置、文件类型和权限设置)
|
|
按照大小查找 -size
-size 选项使我们能够按指定大小查找文件。我们可以将其计量单位指定为以下约定:
- b:512 字节块(默认)
- c:字节
- w:双字节字
- k:KB
- M:MB
- G:GB
|
|
按照权限查找 -perm
合理控制文件的权限是 Linux 管理员的一项重要任务。find 命令的 -perm 选项可以帮助我们按指定权限查找文件
|
|
777 权限的文件,意味着一个文件对其持有者、组和所有用户具有所有的读、写和可执行权限。
按所有权查找 -user
使用 -user 选项指定用户名。
|
|
在找到文件后执行命令 -exec
在大多数情况下,我们希望在找到我们需要的文件后进行后续操作。例如将其删除,或检查它们的详细信息等等。-exec 命令使这些所有事情变得更加容易。
|
|
上述命令在 -exec 选项后是 rm -rf,其用于删除文件。{} 是用于查找结果的占位符。
注意:占位符 {} 非常重要,尤其是在您想删除文件时。因为,如果您不使用它,该命令将对所有文件执行(而不是您刚刚通过 find 命令找到的文件)。
|
|
-exec 选项后面的命令必须以分号 ;
结束。众所周知,转义字符用于去除单个字符的特殊含义。在 Linux 中,反斜杠 \
用作转义字符。所以我们将它用于分号字符。
查找时指定忽略一个目录
如果想查找当前目录下的文件,且忽略 tests 目录
|
|
|
|
不同的表达式之间要用操作符分隔开,如果没有提供操作符,默认使用 -and 操作符。
所以 find . -path ./tests -prune -o -print
命令的完整格式其实是 find . -path ./tests -and -prune -o -print
。
-path pattern
这是一个 test 类型表达式,当 find 命令查找到的文件名完全匹配所给的 pattern 模式时,该表达式返回 true。
这里面最关键的点是,要完全匹配 find 命令查找到的名称,而不是部分匹配,也不是匹配文件的绝对路径名。
查看上面 find . 命令打印的信息,可以看到该命令打印的 tests 目录名是 ./tests,-path 参数要求是完全匹配才会返回 true,所以基于打印结果,就是要写为 -path ./tests 才会返回 true。-path tests 就是 false。
没有提供除了 -prune 表达式之外的其他 action 类型表达式时,默认会对所有返回 true 的文件名执行 -print 表达式,打印该文件名。
类似的,执行 find tests 命令,打印的 tests 目录名是 tests,那么 find tests -path tests 命令可以完全匹配 tests 模式,打印出这个目录名。而 find tests -path ./tests 就匹配不到,没有打印。
总的来说,在 -path 后面跟着的目录名,需要完全匹配 find 命令打印的目录名,而不是部分匹配。如果不确定 find 命令打印的目录名是什么,可以先不加 -path 参数执行一次 find 命令,看打印的文件名是什么,再把对应的文件名写到 -path 参数后面。
忽略多个目录的写法
如果想要忽略多个目录,要使用 -o 操作符把多个 -path pattern 表达式组合起来。
|
|
正则表达式匹配完整路径文件名
在 find 命令里面,-path pattern 表达式和 -name pattern 表达式都是使用通配符来匹配模式,如果想要用正则表达式进行匹配,可以使用 -regex expr 表达式。
|
|
实用用法
如果你的 Linux 服务器上有一个名为 logs 的目录,如何删除该目录下最后一次访问时间超过一年的日志文件呢?
|
|