为什么这个(扩展的)通配符与我试图排除的文件名匹配?

sh.*_*.ll 4 bash wildcards

为什么我运行命令时会显示“myscript.txt”

$ ls !(my)*.txt
myscript.txt
hey.txt
Run Code Online (Sandbox Code Playgroud)

同样,bash 如何解释$ ls !(my)*.txt$ ls !(my*).txt

Sté*_*las 8

!(my)*.txt匹配,myscript.txt因为

  • !(my) 匹配空字符串
  • * 匹配 myscript
  • .txt 匹配 .txt

(或!(my)对比赛myscript*对空字符串,或者!(my)匹配上m*yscript......)。

你想!(my*).txt,如果你想匹配文件名为此在.txt不下手my

请注意,这!(*)是特定于 ksh 的运算符。它现在也支持,bash但只有在extglob选项开启zsh时,但只有在kshglob选项上时才。

zsh也有它自己的extendedglobs ,它带有它的^否定运算符,并且~ 除了/-not 运算符:

set -o extendedglob
ls -ld -- (^my*).txt
ls -ld -- *.txt~my*
Run Code Online (Sandbox Code Playgroud)

/和不操作员可以实现ksh93与:

ls -ld -- @(*.txt&!(my*))
Run Code Online (Sandbox Code Playgroud)

或与bash -O extglob旧版本的 ksh 与

ls -ld -- !(!(*.txt)|my*)
Run Code Online (Sandbox Code Playgroud)

请注意,尽管它们与zsh~运算符不同,因为后者用作整个 glob 模式的最终过滤器,而!(...),@(...)只能对 glob 的单个路径组件进行操作(例如,从 的扩展中*/b*~f*r排除)foo/bar*/b*