欢迎各位兄弟 发布技术文章
这里的技术是共享的
可以看看 /node-admin/12573
find
命令排除目录和文件详解与示例find
是 Linux 中最强大的文件搜索工具之一,经常需要在进行搜索时排除特定目录或文件。下面是详细的排除方法和实际示例。
-prune
排除单个目录语法:
bashfind 搜索路径 -path "要排除的目录路径" -prune -o 其他条件 -print
示例:搜索当前目录但排除 ./cache
目录
bashfind . -path "./cache" -prune -o -name "*.log" -print
-not -path
排除多个目录示例:排除 node_modules
和 .git
目录
bashfind . -type d $ -name "node_modules" -o -name ".git" $ -prune -o -name "*.js" -print
示例:排除 /tmp
目录的搜索
bashfind / -path "/tmp" -prune -o -name "*.conf" -print
!
或 -not
排除特定文件示例:查找所有 .txt
文件但排除 test.txt
bashfind . -name "*.txt" ! -name "test.txt" # 或 find . -name "*.txt" -not -name "test.txt"
示例:查找除 .log
和 .tmp
之外的所有文件
bashfind . -type f ! -regex ".*\.$log\|tmp$$"
bashfind /var/www \ -path "/var/www/cache" -prune -o \ -path "/var/www/temp" -prune -o \ -name "*.php" ! -name "test.php" -print
bashfind ~/Photos \ -type f $ -iname "*.jpg" -o -iname "*.png" $ \ ! -iname "*thumb*" ! -iname "*small*"
bashfind . -type d $ -name ".*" -prune $ -o $ ! -name ".*" -print $
-mindepth
跳过当前目录bashfind . -mindepth 1 -name "*.bak"
bashfind . -type f ! -regex ".*/backup/.*" ! -regex ".*/temp/.*"
bashfind . -path "*/.svn/*" -prune -o -name "Makefile" -print
-prune
必须与 -o
(OR) 组合使用
!
或 -not
必须放在要排除的条件前
使用括号 ()
时需要转义 $
和 $
测试排除效果时可先使用 -print
而不是执行操作
掌握这些排除技巧可以显著提高 find
命令的效率和精确度,特别是在大型项目或复杂目录结构中搜索文件时。
-prune 这里是什么 意思
-prune
在 find
命令中的含义与作用详解-prune
是 find
命令中的一个重要动作(action),表示"修剪"(即排除)找到的目录及其所有子目录,不再深入搜索。
-prune
的核心含义字面意思:prune 英文原意为"修剪树枝",在 find
中引申为"剪除/排除目录"
功能:当 find
遇到匹配 -prune
条件的目录时,会:
记录该目录(如果 -print
存在)
不进入该目录进行递归搜索
跳过其所有子内容
与 -delete
的区别:
-prune
:仅排除搜索,不影响实际文件系统
-delete
:实际删除文件/目录
-prune
基本语法必须与 -o
(OR) 运算符配合使用:
bashfind [路径] -path "要排除的目录" -prune -o [其他条件] -print
当 find
执行时:
先评估 -path "目录" -prune
:
如果匹配:执行 -prune
(跳过该目录)
如果不匹配:继续评估 -o
右侧的条件
-o
表示逻辑"OR":
左侧条件(-path ... -prune
)失败时
才会执行右侧的条件检查
bashfind . -path "./cache" -prune -o -name "*.log" -print
解析流程:
当前文件是 ./cache
目录?
是 → 执行 -prune
(不进入搜索)
否 → 检查是否是 .log
文件 → 打印
bashfind /www $ -path "/www/cache" -o -path "/www/temp" $ -prune -o -name "*.php" -print
括号逻辑:
$ ... $
将多个 -path
条件组合
任意一个 -path
匹配 → 执行 -prune
-o
连接其他条件错误写法:
bashfind . -path "./cache" -prune -name "*.log" # 无效!
正确写法:
bashfind . -path "./cache" -prune -o -name "*.log" -print
-prune
对文件无效-prune
只对目录有效,要排除文件应使用:
bashfind . -name "*.bak" ! -name "important.bak"
用 -path
而非 -name
精确匹配路径
路径模式需包含 /
符号(如 ./cache
而非 cache
)
与 grep -v
等后处理方式相比:
更高效:直接跳过目录树,减少 IO 操作
更安全:避免处理超大目录(如 node_modules
)
例如处理 50GB 的日志目录:
bashfind /logs -path "/logs/archive" -prune -o -name "*.log" -exec rm {} +
可安全跳过 /logs/archive
而不会误删。
find ./ -path './dir0*' -a -prune -o -name *.txt -print 与 find ./ -path './dir0*' -prune -o -name *.txt -print 区别 详解
在Linux的find
命令中,-a
表示逻辑"AND",但在这个具体场景中,这两个命令实际上没有区别。下面详细解析这两个命令以及-a
的作用:
命令A:显式使用-a
bashfind ./ -path './dir0*' -a -prune -o -name *.txt -print
命令B:省略-a
bashfind ./ -path './dir0*' -prune -o -name *.txt -print
-a
的作用:
-a
表示逻辑"AND",是find
命令中的默认连接词
当两个测试条件连续出现时,find
自动认为它们之间是AND关系
因此-path './dir0*' -prune
等同于-path './dir0*' -a -prune
实际等价性:
这两个命令在功能上是完全等价的
-a
是默认的连接操作符,所以可以省略
保留-a
只是让逻辑关系更明确(但非必要)
执行逻辑:
sql如果(路径匹配'dir0*')则(修剪不搜索) 否则如果(文件名匹配*.txt)则(打印)
-a
在更复杂的表达式中,可能需要显式使用-a
来明确逻辑关系:
bashfind . $ -name '*.tmp' -a -mtime +30 $ -o $ -name '*.log' -a -size +1M $
这里的-a
有助于明确分组内的AND关系
*.txt
引用问题: 当前命令中的*.txt
没有引号,可能会被shell先展开(如果当前目录有匹配的.txt文件)。更安全的写法是:
bashfind ./ -path './dir0*' -prune -o -name '*.txt' -print
-print
的位置: 在复杂命令中明确指定-print
可以避免默认打印所有不匹配prune条件的路径
这两个命令的唯一区别是:
前者明确写出了-a
(AND操作符)
后者省略了默认的-a
在实际效果、性能和处理结果上完全没有区别。建议使用更简洁的第二种形式,除非在复杂逻辑表达式中需要明确AND关系时才使用-a
。
-print 作用
在 find
命令中,-print
是一个 默认的动作(action),用于将匹配的文件路径完整打印到标准输出(stdout)。其作用和注意事项如下:
打印匹配的文件路径-print
会将 find
找到的每个满足条件的文件路径(从搜索起始路径开始的相对或绝对路径)逐行输出。
示例:
bashfind ./ -name "*.txt" -print
输出类似:
./file1.txt
./docs/file2.txt
默认行为
如果 find
命令中未指定任何其他动作(如 -exec
、-delete
等),且命令行未使用 -print0
、-printf
等替代选项,find
会自动在末尾隐式加上 -print
。
以下两条命令等价:
bashfind ./ -name "*.txt" find ./ -name "*.txt" -print
与其他动作共存时的行为
如果指定了其他动作(如 -exec
、-delete
),-print
不会自动生效,需显式添加。
示例(删除文件并打印路径):
bashfind ./ -name "*.tmp" -print -delete
例外:-prune
是一个特例,它本身不是动作,所以如果未指定其他动作,find
仍会默认打印未修剪的路径。
替代选项
-print0
:用 \0
(空字符)分隔路径,适合处理含空格/换行符的文件名(通常管道传递给 xargs -0
)。
bashfind ./ -name "*.log" -print0 | xargs -0 rm
-printf
:自定义输出格式(如显示文件名、大小、权限等)。
bashfind ./ -printf "%p - %k KB\n"
调试命令
在执行危险操作(如 -delete
)前,先用 -print
预览哪些文件会被处理:
bashfind ./ -name "*.old" -print # 确认无误后再替换为 -delete
与其他工具协作
将路径传递给其他命令(如 grep
、wc
):
bashfind /var/log -name "*.log" -print | xargs wc -l
显式控制输出
在复杂条件中明确指定输出范围(避免默认打印所有未匹配路径):
bashfind ./ $ -name "*.jpg" -o -name "*.png" $ -print
路径中的特殊字符-print
用换行符分隔路径,若文件名含换行符会引发问题(此时应改用 -print0
)。
性能影响-print
会略微增加开销,但在大多数场景下可忽略不计。
与 -o
的逻辑
在 OR 逻辑(-o
)中,-print
可能需分组使用:
bashfind ./ $ -name "*.txt" -print $ -o $ -name "*.sh" -print $
-print
是 find
最基础的动作,用途包括:
显式输出文件路径
调试搜索条件
兼容性(默认行为)
格式化(结合 -printf
)
在简单搜索时通常可省略,但在复杂命令中明确写出 -print
能让逻辑更清晰。