我正在尝试调整一些完成。假设我有:
$ ls
bar.baz foo_bar.baz foo.bar
如果我希望补全匹配所有不以 baz 结尾的文件:
$ shopt|grep extglob
extglob on
$ compgen -G "*.!(baz)"
foo.bar
排除 glob 按预期工作。但如果我想要所有不以 foo 开头的文件:
$ compgen -G "!(foo)*"
bar.baz
foo.bar
foo_bar.baz
所有文件仍然匹配。想必这是因为*
仍然可以扩展来匹配foo
。是否有一个全局技巧来使用排除,然后使用*
?
正如 Janis 指出的,排除 foo 需要是!(foo*)
,但实际用例是还要匹配扩展名,因此 glob 通常需要采用以下形式!(foo*)*.bar
(仍然无法排除“foo”前缀)。
答案1
您必须*
在否定中包含 the,例如:
ls !(foo*)
编辑(澄清):请求的[扩展]通配模式是!(foo*)
.如果与命令一起使用,compgen
则调用将是,例如:
compgen -G "!(foo*)"
您需要引号才能将模式传递给compgen
未展开的命令。
编辑(问题更改后):对于编辑问题中的完整模式,请尝试@(!(foo*)|*bar)
或之一@(!(bar*)|*foo)
。 (如果这不是您所期望的,请参阅下面的评论。)