我想查找以 _peaks.bed
结尾的文件,但排除 tmp
和 scripts
文件夹中的文件。
我的命令是这样的:
find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)
但它没有用。 tmp
和 script
文件夹中的文件仍会显示。
有人对此有想法吗?
原文由 Hanfei Sun 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想查找以 _peaks.bed
结尾的文件,但排除 tmp
和 scripts
文件夹中的文件。
我的命令是这样的:
find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)
但它没有用。 tmp
和 script
文件夹中的文件仍会显示。
有人对此有想法吗?
原文由 Hanfei Sun 发布,翻译遵循 CC BY-SA 4.0 许可协议
利用
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
或者
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
或者
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
顺序很重要。它从左到右评估。始终从路径排除开始。
不要使用 -not
(或 !
)排除整个目录。使用 -prune
。如手册中所述:
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
并在 GNU 查找手册中:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
实际上,如果您使用 -not -path "./pathname"
, find 将评估 "./pathname"
下每个节点的表达式。
find 表达式只是条件评估。
\( \)
- 分组操作(你可以使用 -path "./tmp" -prune -o -path "./scripts" -prune -o
,但它更详细)。-path "./script" -prune
- 如果 -path
返回 true 并且是一个目录,则为该目录返回 true 并且 不要 进入该目录。-path "./script" ! -prune
- 它评估为 (-path "./script") AND (! -prune)
。它将修剪的“始终正确”恢复为始终错误。它避免打印 "./script"
作为匹配项。-path "./script" -prune -false
- 因为 -prune
总是返回 true,你可以跟随它 -false
做与 !
339639d8fb78 相同的操作-o
- OR 运算符。如果两个表达式之间没有指定运算符,则默认为 AND 运算符。因此, \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
扩展为:
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
打印在这里很重要,因为没有它会扩展到:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
由 find 添加 - 这就是为什么大多数时候,您不需要在表达式中添加它。由于 -prune
返回 true,它将打印“./script”和“./tmp”。
在其他情况下没有必要,因为我们将 -prune
切换为始终返回 false。
提示:可以使用 find -D opt expr 2>&1 1>/dev/null
来查看它是如何优化和扩展的,
find -D search expr 2>&1 1>/dev/null
查看检查了哪个路径。
原文由 f380cedric 发布,翻译遵循 CC BY-SA 4.0 许可协议
7 回答5.3k 阅读
4 回答4k 阅读
2 回答5.9k 阅读✓ 已解决
2 回答2.5k 阅读✓ 已解决
1 回答2.3k 阅读✓ 已解决
2 回答795 阅读✓ 已解决
2 回答3.2k 阅读
以下是您可以使用
find
指定的方法:解释:
find .
- 从当前工作目录开始查找(默认递归)-type f
- 指定find
您只希望结果中的文件-name "*_peaks.bed"
- 查找名称以_peaks.bed
! -path "./tmp/*"
- 排除路径以./tmp/
! -path "./scripts/*"
- 同时排除路径以./scripts/
开头的所有结果测试解决方案:
您非常接近,
-name
选项仅考虑基本名称,其中-path
考虑整个路径 =)