这个关于在 vim 中打开除 [条件] 之外的所有文件的答案:
https://unix.stackexchange.com/a/149356/98426
给出了类似的答案:
find . \( -name '.?*' -prune \) -o -type f -print
(我修改了答案,因为我的问题与 vim 无关)
否定条件位于转义括号中。但是,在我的测试文件中,以下内容
find . -type f -not -name '^.*'
产生相同的结果,但更容易阅读和编写。 -not 方法与 -prune 方法一样,会修剪以 . (点)。我想知道 -not 和 -prune -o -print 方法会产生不同结果的边缘情况是什么。
Findutils 的信息页面内容如下:
-不是表达式: 如果 expr 为假则为真
-prune:如果文件是目录,则不要进入该目录。 (并进一步解释需要 -o -print 来实际排除顶级匹配目录)
它们似乎很难以这种方式进行比较,因为 -not 是一个测试,而 -prune 是一个操作,但对我来说,它们是可以互换的(只要 -o -print 在 -prune 之后)
答案1
首先,请注意这-not
是一个 GNU 扩展,相当于标准!
运算符。相比之下,它几乎没有任何优势!
。
谓词-prune
始终评估为真的并影响目录树的行走方式find
。如果运行的文件-prune
属于以下类型目录(可能在使用-L
//进行符号链接解析后确定),然后将不会下降到其中。-H
-follow
find
所以-name 'pattern' -prune
( 的缩写-name 'pattern' -a -prune
)与相同,-name 'pattern'
只是名称匹配的目录pattern
将是修剪过的,那就find
不会降临到他们身上。
-name '.?*'
.
匹配名称以 1开头的文件特点(其定义取决于当前语言环境)后跟 0 个或多个人物。因此,实际上,它匹配.
后跟一个或多个字符(以免修剪.
起始目录)。
因此,这会匹配隐藏文件,但需要注意的是,它仅匹配那些名称也完全由其组成的文件人物,即当前语言环境中的有效文本(至少对于 GNU 实现而言)。
所以在这里,
find . \( -name '.?*' -a -prune \) -o -type f -a -print
哪个是相同的
find . -name '.?*' -prune -o -type f -print
因为 AND(-a
隐含)优先于 OR(-o
)。
查找以下文件常规的(没有符号链接、目录、fifo、设备...)并且不隐藏并且不在隐藏目录中(假设所有文件路径都是语言环境中的有效文本)。
find . -type f -not -name '^.*'
或其标准等效项:
find . -type f ! -name '^.*'
会找到名称不以^.
.
find . -type f ! -name '.*'
会找到名称不以 开头的常规文件.
,但仍会报告隐藏目录中的文件。
find . -type f ! -path '*/.*'
会忽略隐藏文件和隐藏目录中的文件,但find
仍然会下降到隐藏目录(任何级别深度),只是为了跳过其中的所有文件,因此比使用-prune
.
答案2
-prune
中的谓词删除find
搜索树的一个分支。因此,-prune
如果目录中没有隐藏名称的文件,那么在问题中的第一个命令中使用 as 只会给出与第二个命令相同的结果。
例子:
$ tree -a
.
|-- .hiddendir
| `-- file
`-- dir
`-- file
2 directories, 2 files
$ find . \( -name '.?*' -prune \) -o -type f -print
./dir/file
$ find . -type f ! -name '.*'
./dir/file
./.hiddendir/file
(我-name
在这里更正了测试,因为您似乎使用了无意义的正则表达式,并且我用它!
代替了非标准-not
)。
正如您所看到的,由于名称.hiddendir
与通配模式匹配.?*
,因此使用第一个命令将其从搜索树中删除,并且file
找不到其下面的文件。
在第二个命令中,.hiddendir
目录没有从搜索树中删除,因此file
可以找到其中的文件。