ZhouChuang's Blog ZhouChuang's Blog
首页
  • 常用命令
  • 日常总结
  • Prometheus
  • 基础
  • 常用库
专题
  • 「编码」
更多
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Zhou Chuang

为学日益 为道日损
首页
  • 常用命令
  • 日常总结
  • Prometheus
  • 基础
  • 常用库
专题
  • 「编码」
更多
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Linux 命令

    • 进程管理

    • 磁盘与文件管理

    • 信息显示与文件搜索

      • find 命令介绍
        • 基本语法和结构
        • 常用选项
          • 常用:name、type、size
          • 时间:mtime、atime、ctime
          • 权限:user、group、perm
          • 动作:exec、print
          • 排除:not、empty、prune、maxdepth
          • 符号链接:L、H
          • 正则:regex、iregex
        • 实用案例
          • 按名称或扩展名查找文件
          • 定位目录
          • 按大小或修改时间搜索
          • 按所有权或权限查找文件
          • 使用 -exec 自动化操作
          • 查找空文件和目录
          • 使用 prune 排除目录
        • 组合多个选项进行高级搜索
        • 注意事项
          • 与其他文件搜索工具的比较
        • 最佳实践与技巧
  • 日常的总结

  • Prometheus 技术栈

  • 运维
  • Linux 命令
  • 信息显示与文件搜索
ZhouChuang
2025-05-06
目录

find 命令介绍

find 命令用于在文件系统中定位文件和目录。它能基于各种属性(如名称、类型、大小、权限和时间)进行搜索。对于系统管理员和普通用户而言,find 都是一个提高文件管理效率的强大助手。相较于一些简单的文件搜索方法,find 提供了更强大的功能和灵活性。

# 基本语法和结构

基本格式如下:

find [选项] [路径...] [表达式]
1

其中,各部分组成的含义如下:

  • [选项]:这些是可选的标志,用于修改 find 命令的行为,例如如何处理符号链接。

    主要的符号连接处理选项包括:

    • -P(默认):从不跟随符号链接。find 将直接操作符号链接文件本身。
    • -L:跟随符号链接。当 find 遇到符号链接时,它将操作链接指向的文件或目录,而不是链接本身。
    • -H: 仅在处理命令行参数时跟随符号链接。
  • [路径...]:指定一个或多个开始搜索的目录。可以使用 . 表示当前目录,/ 表示根目录,~ 表示用户主目录,也可以指定具体的目录路径。find 命令也支持指定多个搜索路径。

  • [表达式]:定义用于选择文件和目录的标准。如果没有提供表达式,find 默认执行 -print 动作,即列出所有找到的目录。表达式中通常包含测试(用于检查文件属性的条件)、操作符(用于组合多个测试)和动作(对匹配的文件执行的操作)。

在表达式中,多个条件和操作符的评估存在顺序和优先级 。括号 () 用于分组表达式并控制评估顺序,但需要使用反斜杠进行转义,例如 \( 和 \) 。! 或 -not 用于逻辑非运算 。-a 或 -and (默认情况下是隐式的)用于逻辑与运算 。-o 或 -or 用于逻辑或运算 。

# 常用选项

以下是一些最常用的选项及其详细说明和示例:

# 常用:name、type、size

  • -name <pattern>

    描述:区分大小写的文件名搜索,支持通配符

    示例:find /etc -name apache2.conf

  • -iname <pattern>

    描述:不区分大小写的文件名搜索,支持通配符

    示例:find /etc -iname myfile.txt

  • -type <filetype>

    描述:按文件类型搜索 (f: 文件, d: 目录, l: 符号链接等)

    示例:find /var/log -type f

  • -size <n>[cwbkMG]

    描述:按文件大小搜索 (c: 字节, k: 千字节, M: 兆字节, G: 吉字节)。使用 +, - 或无前缀表示大于,小于或等于

    示例:find / -size +10M

# 时间:mtime、atime、ctime

  • -mtime <n>

    描述:按修改时间搜索(天)。n, +n, -n 分别表示正好,大于或小于 n 天前修改的文件

    示例:find ~ -mtime -7

  • -atime <n>

    描述:按访问时间搜索(天)。n, +n, -n 分别表示正好,大于或小于 n 天前访问的文件

    示例:find ~ -atime +30

  • -ctime <n>

    描述:按状态更改时间搜索(天)。n, +n, -n 分别表示正好,大于或小于 n 天前状态更改的文件

    示例:find. -ctime 1

# 权限:user、group、perm

  • -user <username>

    描述:按文件所有者搜索

    示例:find /var/www/html -user www-data

  • -group <groupname>

    描述:按文件所属组搜索

    示例:find /home -group developer

  • -perm <mode>

    描述:按精确权限模式(八进制)搜索

    示例:find. -perm 0600

# 动作:exec、print

  • -exec <command> {} \;

    描述:对找到的每个文件执行指定的命令。{} 是文件名占位符,\; 表示命令结束

    示例:find . -name "vultr.txt" -exec ls -l {} \;

  • -print

    描述:打印找到的文件的路径名(默认动作)

    示例:find /etc -name apache2.conf -print

# 排除:not、empty、prune、maxdepth

  • -not <expression>

    描述:逻辑非运算,否定表达式的结果

    示例:find /etc -not -name "*.txt"

  • -empty

    描述:查找空文件或空目录

    示例:find /etc -type f -empty

  • -maxdepth <levels>

    描述:限制搜索的最大深度

    示例:find / -maxdepth 3 -name "my_file.txt"

  • -prune

    描述:从搜索中排除指定的目录

    示例:find. -name SCCS -prune -o -print

# 符号链接:L、H

  • -L

    描述:跟随符号链接

    示例:find -L /usr/bin -name "ls"

  • -H

    描述:在命令行上跟随符号链接

    示例:find -H link_to_dir -name "file.txt"

# 正则:regex、iregex

  • -regex <pattern>

    描述:使用区分大小写的正则表达式匹配整个路径名。

  • -iregex <pattern>

    描述:使用不区分大小写的正则表达式匹配整个路径名。

# 实用案例

# 按名称或扩展名查找文件

  • 查找特定文件:

    find /home/user -name "document.pdf"
    
    1
  • 查找具有特定扩展名的文件:

    find /var/log -name "*.log"
    
    1
  • 不区分大小写地查找文件:

    find. -iname "readme.txt"
    
    1

# 定位目录

  • 按名称查找目录:

    find / -type d -name "backup"
    
    1

# 按大小或修改时间搜索

  • 查找大文件:

    find / -type f -size +1G
    
    1
  • 查找最近修改的文件:

    find /var/log -mtime -7
    
    1
  • 查找最近 24 小时内修改的文件:

    find ~ -type f -mtime -1
    
    1

# 按所有权或权限查找文件

  • 查找属于特定用户的文件:

    find /home/user -user john
    
    1
  • 查找具有特定权限的文件:

    find . -type f -perm 644
    
    1

# 使用 -exec 自动化操作

  • 删除临时文件:

    find /tmp -name "*.tmp" -exec rm {} \;
    
    1
  • 更改文件权限:

    find . -type f -perm 777 -exec chmod 644 {} \;
    
    1
  • 复制文件:

    find . -name "*.txt" -exec cp {} /backup \;
    
    1

说明:

  • {}: 这是一个占位符。在执行命令时,{} 会被替换成 find 当前找到的那个匹配项的文件名或路径。

  • ;: 这是结束 -exec 命令的标志。需要用反斜杠 \ 进行转义,因为分号在 shell 中有特殊含义。使用 ; 时,找到的每一个匹配项都会 独立地 执行一次命令。

# 查找空文件和目录

find . -type f -empty

find . -type d -empty
1
2
3

# 使用 prune 排除目录

基本语法:

-path <要排除的目录模式> -prune
1

更常见的用法是结合逻辑操作符:

find <起始路径> \( <排除条件> -prune \) -o \( <查找条件> -print \)
1
  • -o: 逻辑或操作符。如果左边的条件(排除并剪枝)不满足,则执行右边的条件。
  • -print: 打印找到的匹配项(默认动作,但显式写出更清晰)。

为什么需要 -o ?

image-20250506132749648

  • 下面是没有 -o 的情况:

    find . -path "./data" -prune -print

    ​ image-20250506132828361

    这只会找到并打印 ./data 这个目录本身,但不会进入 data 目录,也不会打印 data 目录下的内容。它也不会查找和打印其他目录下的文件。

  • 而加上 -o 后:

    find . \( -path "./data" -prune \) -o \( -print \)

    image-20250506132931438

解释

  • 当 find 遍历到 ./data 目录时,它匹配了 -path "./data"。
  • -prune 告诉 find 不要进入 ./data 目录。
  • 因为匹配了 -prune,所以 \( -path "./data" -prune \) 这个组合条件为真。
  • 由于是 -o 操作,左边的条件为真,右边的条件 \( -print \) 就不会被执行,所以 ./data 这个目录本身不会被打印(除非你在 -prune 前面加上了 -print)。
  • 当 find 遍历到 非 ./data 的其他目录或文件时,它不匹配 -path "./data"。
  • \( -path "./data" -prune \) 这个组合条件为假。
  • 由于是 -o 操作,左边的条件为假,右边的条件 \( -print \) 就会被执行,所以其他目录和文件会被打印出来。

简而言之,\( <排除条件> -prune \) -o \( <查找条件> \) 的意思是:

如果当前项符合排除条件(并且是目录),则不对其进行进一步搜索(prune),并且该项不符合本次查找的结果;否则,如果当前项符合查找条件,则将其作为结果。

  • find . \( -path "./data" -prune \) -o \( -name "*.log" -print \)

image-20250506133949001

​ data/subdir/file2.log 被成功排除。

  • 排除多个目录

    find . \( -path "./data" -prune -o -path "./scripts" -prune \) -o \( -name "*.log" -print \)

    这个命令会排除 data 目录和 scripts 目录,然后在其他地方查找 .log 文件。

  • 排除特定文件类型或属性的目录

    你可以结合其他测试条件来排除目录,例如排除所有权限为 700 的目录:

    find . \( -type d -perm 700 -prune \) -o \( -print \)

注意事项:

  • -prune 只对目录有效。如果你匹配到一个文件并使用 -prune,它没有任何效果。
  • -prune 通常与 find 的 遍历顺序 紧密相关。它在 find 进入 目录之前评估,如果匹配并使用了 -prune,find 就不会进入该目录。
  • 将 -prune 放在 \( ... \) 结构中,并与 -o 结合使用是处理排除条件的标准且健壮的方法。

# 组合多个选项进行高级搜索

find 命令允许使用逻辑运算符 (-a, -o) 组合多个选项,从而实现更高级的搜索

  • 查找符合多个条件的文件(隐式 -a):find / -name "*.txt" -size +1M

  • 使用 -o 查找符合任一模式的文件:find. -name "*.txt" -o -name "*.pdf"

  • 将 -not 与其他选项组合使用:find /home -user john -not -name "temp*"

  • 示例:

    • 查找目录中的所有 .txt 和 .html 文件:

      find /path -name "*.txt" -o -name "*.html"
      
      1
    • 查找大于 10MB 且在过去 7 天内修改过的文件

      find / -size +10M -mtime -7 
      
      1
    • 查找属于特定用户且具有特定权限的文件

      find /var/www -type f -user www-data -perm -g=w 
      
      1

对于更复杂的逻辑表达式,可以使用括号进行分组,以明确运算顺序 。

例如:find / \( -name "a.out" -o -name "*.o" \) -atime +7 -exec rm {} \; 。

组合多个选项和使用逻辑运算符的能力极大地增强了 find 的功能,使其能够执行高度特定和精细的搜索。这对于需要满足多个条件的复杂文件系统管理任务至关重要。括号的使用为这些复杂表达式中的评估顺序提供了必要的控制。

# 注意事项

性能考量:

  • 搜索整个文件系统 (/) 可能会很慢;尽可能指定具体的搜索路径 。
  • 使用 -prune 排除不必要的目录 。
  • -exec {} + 比 -exec {} \; 更有效率,因为它允许将多个文件名传递给单个命令调用。

错误处理与权限:

  • 使用 2>/dev/null重定向错误消息
  • 使用 sudo 克服权限拒绝错误 。

# 与其他文件搜索工具的比较

命令 搜索方法 速度 准确性 主要用途
find 实时搜索文件系统 较慢 实时 基于各种属性查找文件和目录,执行复杂操作
locate 搜索预建数据库 较快 可能过时 快速按名称查找文件,但数据库可能需要定期更新 (updatedb)
grep 在文件内容中搜索模式 取决于文件大小 实时 在文件内容中查找特定的文本模式或字符串,常与 find 结合使用查找包含特定内容的文件

# 最佳实践与技巧

  • 尽可能从最具体的目录开始搜索,以提高性能 。

  • 尽早在表达式中使用 -type 来缩小搜索范围 。

  • 使用引号引用 -name 和 -iname 使用的模式,以防止 shell 扩展 。

  • 在使用 -exec 执行可能具有破坏性操作(如 rm)的命令之前,先使用 -print 测试复杂的命令 。

  • 在搜索系统目录时,请注意权限错误;考虑使用 sudo 或重定向错误 。

  • 使用 -maxdepth 和 -mindepth 控制搜索范围并提高性能 。

  • 理解使用 -L 和 -H 处理符号链接的影响 。

  • 对于在找到的文件上执行复杂操作,可以考虑结合使用 xargs 和 find 。

#find#文件查找
上次更新: 2025/05/06, 13:52:56
交换分区的配置
进程管理工具:supervisor

← 交换分区的配置 进程管理工具:supervisor→

最近更新
01
交换分区的配置
04-09
02
top 命令介绍
04-08
03
日志库 Zap
03-30
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Zhou Chuang 版权所有| 鲁ICP备2021031629号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式