Bash 为什么glob`*[!t]*`返回名称中包含`t`的文件?

Bash 为什么glob`*[!t]*`返回名称中包含`t`的文件?,bash,shell,unix,Bash,Shell,Unix,在阅读了shell中通过以下命令打印的结果后,我真的不知道,我正在使用(bash)作为shell。给定此目录层次结构: /sub2 s.py t2.txt nametoname.txt bees.txt /sub22 据我所知,echo的参数将被扩展以匹配任何不包含字母t的文件名,但结果正好相反,为什么 此命令输出包含字母t的所有文件名: $ echo *[t]* nametname.txt t2.txt 在上一个命令中,我只是将[t]反求为[!t]

在阅读了shell中通过以下命令打印的结果后,我真的不知道,我正在使用(bash)作为shell。给定此目录层次结构:

/sub2
    s.py
    t2.txt
    nametoname.txt
    bees.txt
    /sub22

据我所知,
echo
的参数将被扩展以匹配任何不包含字母t的文件名,但结果正好相反,为什么

此命令输出包含字母t的所有文件名:

$ echo *[t]*
nametname.txt t2.txt

在上一个命令中,我只是将
[t]
反求为
[!t]
,然后在我的期望中,它应该执行与第二个命令相反的操作

是对括号表达式求反的标准字符
*[!t]*
表示匹配零个或多个任意字符,后跟除
t
之外的任何字符,后跟零个或多个任意字符。换言之,匹配任何包含
t
以外字符的文件名。它不匹配的是仅由
t
s:
t
tt
ttt
等组成的文件名

如果您只想匹配不包含任何
t
的文件名,请参阅Charles Duffy的答案,因为他比我快了一步。

此glob:

echo *[!t]*
将查找至少包含一个非
t
字符的任何文件名

因此,如果您的文件名为
t
tt
ttt
,那么这些文件名将不会使用此glob列出

解决方案:

如果要列出其中没有字母
t
的文件名,可以使用此
find
命令:

find . -maxdepth 1 -mindepth 1 -not -name '*t*'

您还可以添加
-type f
仅用于列出文件,或
-type d
仅用于列出目录。

正如其他答案所给出的那样,
*[!t]*
返回带有任何非
t
字符的文件

他们尚未提供的是一个解决方案:

shopt -s extglob  ## enable extglobs
echo !(*t*)       ## list files with names not containing t

请参见

为了与glob的大小写严格性保持一致,您可能应该在此处使用
-name
,而不是
-iname
。然后我可以说
echo*[t]*
将匹配任何包含至少一个t的文件名。
shopt -s extglob  ## enable extglobs
echo !(*t*)       ## list files with names not containing t