Why is 'myscript.txt' displayed when I run the command

$ ls !(my)*.txt

and on the same note, how is bash interpreting $ ls !(my)*.txt and $ ls !(my*).txt?


!(my)*.txt matches on myscript.txt because

  • !(my) matches on the empty string
  • * matches on myscript
  • .txt matches on .txt

(or !(my) matches on myscript and * on the empty string, or !(my) matches on m and * on yscript...).

You want !(my*).txt if you want to match on file names that end in .txt and don't start with my.

Note that !(*) is a ksh-specific operator. It's now also supported by bash but only when the extglob option is on and by zsh, but only when the kshglob option is on.

zsh also has its own extendedglobs which come with its ^ negation operator and ~ except / and-not operator:

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

The except / and-not operator can be implemented in ksh93 with:

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

or with bash -O extglob and older version of ksh with

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

Note though that they differ from zsh's ~ operator in that the latter applies as a final filter on whole glob pattern, while the !(...), @(...) can only operate on a single path component of the glob (for example */b*~f*r excludes foo/bar from the expansion of */b*)

  • I'm still confused on why !(my) matches on empty string, because ! matches only when none of the pattern matches, which shouldn't expand myscript.txt, therefore not including it in the result :/ – sh.3.ll Oct 24 '19 at 17:30
  • Does it mean that even though 'my' matches with 'my', bash is comparing 'my' with just 'm' and rest is matched with *.txt? – sh.3.ll Oct 24 '19 at 17:35
  • @sh.3.ll !(my) matches any string except my, including the empty string. * matches any string including my (and the empty string). This means that !(my)*.txt matches myfile.txt. I don't know how this can be said more clearly. What part of the filename that !(my) matches and what part * matches is less important. – Kusalananda Oct 24 '19 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.