Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the glob `*[!t]*` return files whose names contain `t`s?

Tags:

bash

shell

unix

I have really no idea after reading glob (programming) of the results printed by following command in shell, I'm using (bash) as my shell. Given this directory hierarchy:

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

$ echo *[!t]*
bees.txt nametname.txt s.py sub22 t2.txt 

In my understanding the arguments to echo will be expanded to match any filenames that don't contain the letter t, but the result was quite the opposite, why?

This command outputs all filenames that contain the letter t:

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

In the previous command I just negated [t] to [!t], then in my expectation it should do the opposite of the second command.

like image 842
direprobs Avatar asked Dec 06 '25 17:12

direprobs


2 Answers

This glob:

echo *[!t]*

Will find any filename that at least one non-t character in it.

So, If you have filenames as t, tt, ttt then those filenames won't be listed using this glob.

Solution:

If you want to list filenames that don't have letter t in it then you can use this find command:

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

You may also add -type f for listing files only or -type d for listing directories only.

like image 190
anubhava Avatar answered Dec 09 '25 14:12

anubhava


As other answers have given, *[!t]* returns files with any non-t character.

What they haven't yet provided is a workaround:

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

See http://wiki.bash-hackers.org/syntax/pattern#extended_pattern_language

like image 26
Charles Duffy Avatar answered Dec 09 '25 14:12

Charles Duffy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!