Bash - Excluding subdirectories using the find command
我正在使用find命令获取某些文件所在文件夹的列表。但是,由于某些子目录的权限拒绝错误,我想排除某个子目录名。我已经尝试了我在这里找到的这些解决方案:
1 2 3 | find /path/to/folders -path"*/noDuplicates" -prune -type f -name"fileName.txt" find /path/to/folders ! -path"*/noDuplicates" -type f -name"fileName.txt" |
以及这些命令的一些变体(例如路径名的变体)。在第一种情况下,它根本找不到文件夹,在第二种情况下,我再次得到错误,所以我猜它仍然试图访问这个目录。有人知道我做错了什么,或者有人对此有不同的解决方案吗?
为了补充Olim的有用答案,并解决OP对需要
-prune 与每个find primary(操作或测试,在gnu语言中)一样,返回一个布尔值,在-prune 的情况下,该布尔值始终是true 。- 如果没有显式的操作符,primaries就隐式地与
-a (-and )联系在一起,就像它的兄弟-o (-or 执行短路布尔逻辑一样。 -a 的优先级高于-o 。
有关所有
因此,公认的答案,
1 | find . -path ./ignored_directory -prune -o -name fileName.txt -print |
等价于(括号用于使计算优先级显式化):
1 2 3 | find . \( -path ./ignored_directory -a -prune \) \ -o \ \( -name fileName.txt -a -print \) |
由于短路适用,因此评估如下:
- 匹配
./ignored_directory 的输入路径会导致-prune 被评估;由于-prune 总是返回true 的值,因此短路会阻止-o 运算符的右侧被评估;实际上,不会发生任何事情(忽略输入路径)。 - 输入路径与
./ignored_directory 不匹配,由于短路,立即再次在-o 的右侧继续评估:- 只有当输入路径的文件名部分与
fileName.txt 匹配时,才是-print 主要的评估值;实际上,只打印文件名与fileName.txt 匹配的输入路径。
- 只有当输入路径的文件名部分与
编辑:尽管我最初在这里声明了什么,但这里的
相比之下,让我们考虑一下错误地不使用
1 | find . -path ./ignored_directory -prune -name fileName.txt -print |
这相当于:
1 | find . -path ./ignored_directory -a -prune -a -name fileName.txt -a -print |
这将只打印修剪后的路径(也与
关于
POSIX要求,如果
- 产出型初级产品,如
-print 本身 - 执行某物的初选,如
-exec 和-ok 。 - (给出的示例primary对于
find 的posix规范是详尽的,但是实际的实现(如gnufind 和bsdfind )添加了其他的,例如生成-print0 primary的输出和执行-execdir primary的输出)
将
这很方便,因为它允许您编写诸如
但是,在某些情况下,需要一个明确的
假设我们在接受的答案末尾没有指定
1 | find . -path ./ignored_directory -prune -o -name fileName.txt |
由于表达式中现在没有生成或执行primary的输出,因此计算结果为:
1 | find . \( -path ./ignored_directory -prune -o -name fileName.txt \) -print |
这将无法按预期工作,因为如果整个括号表达式的计算结果为true(在本例中错误地包括修剪过的目录),它将打印路径。
相反,通过将
1 | find . -path ./ignored_directory -prune -o \( -name fileName.txt -print \) |
相反,如果左侧为真,则只执行
编辑(添加了行为规范详细信息)
删除find中所有拒绝权限的目录使用GNUSED。
规范行为详细信息-在此解决方案中,我们希望:
基本设计模式为:
1 | find ... \( -readable -o -prune \) ... |
例子
1 | find /var/log/ \( -readable -o -prune \) -name"*.1" |
谢谢mklement0
根据我之前的评论,这适用于我的Debian:
1 | find . -path ./ignored_directory -prune -o -name fileName.txt -print |
或
1 | find /path/to/folder -path"*/ignored_directory" -prune -o -name fileName.txt -print |
或
1 | find /path/to/folder -name fileName.txt -not -path"*/ignored_directory/*" |
分歧在这里争论得很好。
问题在于
1 | find /path/to/folders ! -path"*noDuplicates*" -type f -name"fileName.txt" |