find 查找文件
版权声明:原创文章,未经授权,请勿转载
find 是 Unix-like 操作系统中的一个命令行实用工具,可以用来查找、筛选指定的文件或目录,也可以指定过滤条件及行为,提供了很高的灵活度及便利。
find [path...] [expression]
find
搜索给定路径(path...)目录树上的每一个文件名,并从左至右计算给定的 表达式(expression),按照优先规则进行匹配,直到得出结果,然后 find
移向下一个文件名。
当所有文件都成功处理时 find
退出并返回状态值 0。如果发生错误则返回一个大于 0 的值。
表达式(expression)
表达式是由 选项、测试、动作 组成。以运算符分开,忽略运算符的时候,默认使用 -and
连接。如果表达式没有包含 -prune
以外的动作,当表达式为真时会执行 -print
动作。
- 选项 指定执行测试和动作时的一些选项,影响所有的操作,且总是返回真值。
- 测试 在文件名上执行条件匹配,并返回匹配结果(一个真值或一个假值)。
- 动作 在文件名上执行一个操作,并返回执行结果(一个真值或一个假值)。
连接运算符
( expr )
强制优先
! expr
-not expr
如果 expr 是 false 则返回 true
expr1 expr2
expr1 -a expr2
expr1 -and expr2
expr1 和 expr2 都为真时返回真。
expr1 -o expr2
expr1 -or expr2
expr1 或 expr2 其中之一为真时返回真。
expr1 , expr2
expr1 和 expr2 都会被执行。expr1 的值被忽略,结果值是 expr2的值。
常用选项
-
-follow
不检索符号链接,含了-noleaf
。 -
-maxdepth levels
搜索给定路径(path...)的下层目录时,最深不超过levels(一个非负整数) 层。-maxdepth 0
意味着只在给定路径的目录中执行测试和动作。 -
-mindepth levels
不在levels(一个非负整数)层之内执行任何测试和动作。-mindepth 1
意 味着处理所有的文件,除了命令行参数指定的目录中的文件。 -
-mount
不进入处于其它文件系统之上的目录。可以用-xdev代替,从而和一些其他版本的 find 兼容。
常用测试(tests)
-
-name pattern
匹配基本的文件名与shell
模式pattern
相匹配. -
-iname pattern
和-name
类似,但是匹配时是不区分大小写的。 -
-path pattern
文件名与shell
模式pattern
相匹配。元字符不会对/
或.
做特殊处理。 -
-ipath pattern
和-path
类似,但是匹配时是不区分大小写的。 -
-empty
匹配文件是空的普通文件或者空目录 -
-readable
匹配当前用户可读的文件。 -
-writable
匹配当前用户可写的文件。 -
-perm mode
匹配文件权限【刚好等于】mode的文件 -
-perm -mode
匹配文件权限【完全包括】mode的文件 -
-perm /mode
匹配文件权限【包含任意】mode的文件 -
-type c
匹配文件是 c 类型的, 类型可取值如下:b
特殊块文件(缓冲的)c
特殊字符文件(不缓冲)d
目录p
命名管道 (FIFO)f
普通文件l
符号链接s
套接字D
门 (Solaris 特有)
-
数字类型的参数可以指定 支持的参数: (-amin, -mtime, -gid, -inum, -links, -size, -uid, -used)
+n
是比 n 大,-n
是比 n 小,n
正好是 n 。
-
-size [cwbkMG]
匹配文件大小, 依次是 字节数, 双字节的字, 512字节的块, kb, MB, GB。 -
-uid n
用户的ID(UID in/etc/passwd
) -
-gid n
组名的ID(GID in/etc/group
) -
-user name
用户名 -
-group name
组名 -
-nouser
匹配文件拥有者不存在于/etc/passwd
的文件 -
-nogroup
匹配文件拥有组不存在于/etc/group
的文件 -
-mtime n
在之前n天【当天】被变更内容的文件 -
-mtime +n
在n天之前【不含n天,过去到n天】被变更内容的文件 -
-mtime -n
在n天之内【包含n天,n天到现在】被变更内容的文件 -
-newer file
列出比file更新的文件
动作(action)
-delete
- 删除文件或目录,如果移除成功,则为True。如果删除失败,则会打印错误消息,并且Find的退出状态将是非零的(当最终退出)。
- 警告:
-delete
放在表达式的开头,将导致尝试删除 起始点 以下的所有内容。-delete
操作将无法删除目录,除非它是空的。
-exec command
执行 command;如果命令返回状态值0,那么exec
返回true。所有find
其余的命令行参数将作为提供给命令的参数,直到遇到一个由;
组成的参数为止。命令的参数中,字符串{}
将以正在处理的文件名替换。-print
在标准输出打印文件全名,然后是一个换行符。(默认动作)-print0
在标准输出中打印出完整的文件名,然后是一个(null)空字符。这样可以正确地解释包含换行符或其他类型空格的文件名,以便程序能够正确处理find
的输出。此选项与xargs
的-0
选项相对应。-printf format
在标准输出打印 format 格式化后的内容。-prune
如果该文件是一个目录,则不进入该目录。如果指定了 -depth,则 -prune 不起作用。
例子
# 在/home/zero中查找空目录
find /home/zero -type d -empty
# 将当前目录下(包括子目录)所有dos格式的文件转换为unix格式
find . -type f -print0 | xargs -0 dos2unix --
# 删除/tmp目录下所有名为 core 的文件,前提是文件名中不存在 换行、单双引号,空格。
find /tmp -name core -type f -print | xargs /bin/rm -f
# 与上面相同,但更安全的版本
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
# 为每个文件执行一个命令(大括号用单引号括起来,以防止它们被解释为shell脚本标点符号。分号同样受到反斜杠的保护)
find . -type f -exec file '{}' \;
# 忽略.git目录及其下的文件(小括号通过 '\' 转义, '*' 需要用引号扩起来, 否则会被 shell 处理为文件名)
find . ! \( -path '*/.git/*' -o -name '.git' \)
# 与上面相同,但更推荐的版本
find . -name .git -prune -o -print
# 列出当前目录下所有build目录(不包含./build)
# 条件: 是目录 and 不是 ./build and 名字是 build
find . -type d ! -path ./build -name build
# 列出./patchs下的文件夹(排除自己 ./patchs 与 子文件夹)
find ./patchs -type d ! -name patchs -prune
# xargs 调试方式
# -0: 输入以 \0 分隔
# -i: {} 替换为输入内容
find . -type d ! -path ./build -name build -print0 | xargs.exe -0 -i echo "dir: {}"
find . -type d ! -path ./build -name build -print0 | xargs.exe -0 -i echo "rm -rfi {}"
参考
- Man Pages find:
https://man7.org/linux/man-pages/man1/find.1.html - Man Pages(zh_CN) find:
https://manpages.debian.org/stretch/manpages-zh/find.1.zh_CN.html
Comments ()