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

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

为什么是'myscript.txt'当我运行命令时显示

$ ls !(my)*.txt
myscript.txt
hey.txt

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

答案1

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

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

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

!(my*).txt如果您想匹配以 . 结尾.txt但不以 . 开头的文件名,则需要这样做my

请注意,这!(*)是特定于 ksh 的运算符。现在也支持 bybash但仅当extglob选项打开时和 by zsh,但仅当kshglob选项打开时。

zsh也有它自己的extendedglobs 和它的^否定运算符~ 除了/并不是操作员:

set -o extendedglob
ls -ld -- (^my*).txt
ls -ld -- *.txt~my*

除了/并不是运算符可以ksh93通过以下方式实现:

ls -ld -- @(*.txt&!(my*))

或与bash -O extglob旧版本的 ksh 一起使用

ls -ld -- !(!(*.txt)|my*)

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

相关内容