我使用find命令获取某些文件所在的文件夹列表。但由于某些子目录的权限被拒绝错误,我想排除某个子目录名称。 我已经尝试过这里找到的解决方案:
find /path/to/folders -path "*/noDuplicates" -prune -type f -name "fileName.txt"
find /path/to/folders ! -path "*/noDuplicates" -type f -name "fileName.txt"
这些命令的一些变体(例如路径名的变体)。 在第一种情况下它根本找不到文件夹,在第二种情况下我再次得到错误,所以我猜它仍然试图访问这个目录。有谁知道我做错了什么,或者有没有人为此做出不同的解决方案?
答案 0 :(得分:3)
补充olivm's helpful answer并解决OP的困惑需要-o
:
-prune
,因为每个find
主要(动作或测试,在GNU中说),返回布尔,并且该布尔始终为{{1} } {/ strong>,如果是true
。-prune
(-a
)隐式关联,与其兄弟-and
(-o
)执行短路< / em>布尔逻辑。-or
的优先级高于-a
。 有关所有-o
概念的摘要,请参阅https://stackoverflow.com/a/29592349/45375
因此,接受的答案,
find
等效于(括号用于使评估优先级明确):
find . -path ./ignored_directory -prune -o -name fileName.txt -print
由于短路适用,因此评估如下:
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
在-print
的右侧需要-o
;没有它,暗示 -print
将适用于整个表达式,因此 打印 left - 手边比赛;请参阅下面的背景信息。
相比之下,让我们考虑错误地使用-o
:
find . -path ./ignored_directory -prune -name fileName.txt -print
这相当于:
find . -path ./ignored_directory -a -prune -a -name fileName.txt -a -print
这将仅打印已修剪的路径(也与-name
过滤器匹配),因为-name
和-print
原色(隐含地)与逻辑AND连接;
在这种特定情况下,由于./ignored_directory
也不能匹配fileName.txt
,因此没有打印,但如果-path
的参数是 glob , 可以获得输出。
关于 find
隐式使用-print
的一句话:
POSIX mandates如果find
命令的表达式为WHOLE,则不包含
-print
本身-exec
和-ok
find
的 POSIX 规范是详尽无遗的,但实际的实现,如GNU find
和BSD find
添加其他产品,例如产生产出的-print0
主要产品和正在执行的-execdir
主要产品 -print
隐式应用,就好像表达式被指定为:
\( expression \) -print
这很方便,因为它允许您编写find .
等命令,而无需附加-print
。
但是,在某些情况下,需要明确的-print
,如下所示:
我们说在接受的答案结尾处我们没有指定-print
:
find . -path ./ignored_directory -prune -o -name fileName.txt
由于现在表达式中没有输出生成或执行主要内容,因此将其评估为:
find . \( -path ./ignored_directory -prune -o -name fileName.txt \) -print
这不会按预期工作,因为如果整个括号表达式的计算结果为true,它将打印路径,在这种情况下错误地包含已修剪的目录。
相比之下,通过将-print
显式附加到-o
分支,仅当-o
表达式的右侧评估为true时才会打印路径;使用括号使逻辑更清晰:
find . -path ./ignored_directory -prune -o \( -name fileName.txt -print \)
相反,如果左侧是真的,则仅执行-prune
,这不会产生任何输出(并且因为整体表达式包含-print
, -print
未被隐式应用。)
答案 1 :(得分:1)
按照我之前的评论,这适用于我的Debian:
find . -path ./ignored_directory -prune -o -name fileName.txt -print
或
find /path/to/folder -path "*/ignored_directory" -prune -o -name fileName.txt -print
或
find /path/to/folder -name fileName.txt -not -path "*/ignored_directory/*"
差异很有争议here
答案 2 :(得分:1)
修改(添加了行为规范详情)
使用gnufind。
规范行为详细信息 - 在此解决方案中,我们希望:
基本设计模式是:
find ... \( -readable -o -prune \) ...
实施例
find /var/log/ \( -readable -o -prune \) -name "*.1"
\ {感谢} mklement0
答案 3 :(得分:-1)
问题在于find
评估您传递给-path
选项的表达式的方式。
相反,你应该尝试类似的东西:
find /path/to/folders ! -path "*noDuplicates*" -type f -name "fileName.txt"