When practicing regex in Bash I tried to match the entire set/search-pattern inside the brackets.

Instead, I matched just each single character in them.

For example, with

touch a.c a.h a.o a.cho
ls *.[cho]

The ls matched:


but it didn't match the entire set as in a.cho.

Why didn't I match the entire set as well and how is it possible to do so?


You're not using regular expressions here, but filename globbing patterns.

The [...] will only ever match a single character (this happens to be the same between filename globbing patterns and regular expressions), which is why it does not match the three characters cho ([cho] means "one of c, h and o").

To match all names starting with a. use a.*.

To match all names starting with a. and then directly afterwards ending in either c, h, o or cho, first set the extglob shell option with shopt -s extglob and use a.@([cho]|cho).

A brace expansion like a.{c,h,o,cho} would generate the filenames on the command line, but gives no guarantee that those files actually exists.

  • Oh crap, why do I sometimes call globbing regex. I must stop this forever. But can't we philosophize and say it is a "type" of regex just like JavaScript has it's "type of regex"? I know it's unorthodox, but is it enough false?... – user9303970 Apr 24 '18 at 15:12
  • Can we match all four endings in Bash globbing in one pattern? – user9303970 Apr 24 '18 at 15:13
  • @user9303970 See updated answer. Sorry for mentioning the +(...) pattern before. I rarely use the extended globbing patterns, so I had to do some testing. @(...) is what you may want to use. – Kusalananda Apr 24 '18 at 15:29
  • If you want to match anything that has at least one of those characters after the final dot, use *.+([cho]) (with extglob). That would match any and all of a.c, a.h, a.ch, a.cho etc. – ilkkachu Apr 24 '18 at 16:14

You could use bash Brace Expansion which is not a pattern, but a list of strings

ls *.{c,h,o,cho}

The shell expands that before the ls command is executed to

ls *.c *.h *.o *.cho

Since brace expansion occurs before filename expansion, we can put the glob pattern inside the braces

ls *.{[cho],cho}

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.