我不明白 find -not 是如何工作的。
假设我想找到树中的所有 .git 目录。
find -type d -iname .git
没问题,但是假设我有一些我不喜欢包含的目录,有问题时它们可以称为“旧”和“备份”。
我可以通过管道发送到 grep -v ,这样就可以正常工作了。
find -type d -iname .git | grep -v old | grep -v backup
但是当我浏览 find 的手册页时,我注意到有一个 -not ,但我不知道它是如何工作的。
我这样尝试过,但他不排除旧目录。
find -type d -iname .git -not -iname old
find-not 是如何工作的?我可以用它来发现问题吗?
答案1
find 处理这种情况有一点复杂:
如果表达式不包含除 之外的任何操作
-prune
,
因此,明确打印您想要的部分:
find -type d \( -iname old -prune -o -iname backup -prune -o -iname .git -print \)
完全避免搜索旧树和备用树。
答案2
您可以通过指定排除目录-path
:
find . -type d \( -iname .git ! -path "*/old/*" ! -path "*/backup/*" \)
请注意,-not
在 GNU 中find
与 POSIX 相同,!
但不兼容。
引用自man find
:
! expr True if expr is false. This character will also usually need
protection from interpretation by the shell.
-not expr
Same as ! expr, but not POSIX compliant.
答案3
你需要-prune
选择find
,这真的很棘手。它需要使用too-path
来代替-name
。
我想你想用这个:
find . -type d \( -path '*/old' -prune -o -iname '.git' -print \)
的效果-not
是通过
- 匹配旧的“旧”,而donig什么也没有
- 或(使用选项 -o)
- 匹配“.git”并打印名称
- 或(默认)
- 不执行任何操作(因为 find 的正常默认操作(
-print
命令行末尾的隐式操作)已被禁用(如果-print
已使用)
我认识到其他变体,同时看着命令行上更复杂,可能更容易使用,例如因为使用了不同的逻辑表达式,以及默认操作的更改。
另一方面,-prune
当其他语法因为太长而难以阅读时,涉及的变体更容易泛化到更复杂的情况。
答案4
find -type d -iname .git -not -iname old
这匹配被调用.git
和未被调用的目录old
。由于.git
无法调用被调用的目录old
,因此可以删除该-not -iname old
部分而不改变命令的含义。
-not
说“不匹配”,但不是“不递归”。有一种不同的方式来表达“不要递归”:这是一个名为 的操作-prune
。以下命令的意思是“递归遍历所有目录 ( find
),但在名为old
( -iname old -prune
) 的目录处停止,并打印名为 ( ) 的目录.git
”:
find -iname old -prune -o -type d -iname .git -print
这被解析为( -iname old -prune ) -o ( -type d -iname .git -print )
. Find 的作用是查找满足条件-iname old
或( -o
) 的文件-type d -iname .git
。当文件满足第一个条件时,-prune
执行操作(从遍历的树中修剪,即不递归)。当文件满足第二个条件时,-print
将执行该操作。由于打印是默认操作,因此您可以省略-print
。