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